diff --git a/Gemfile.lock b/Gemfile.lock index a122c1a..4cf203e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,6 +2,7 @@ PATH remote: . specs: middleman-react (0.13.3) + coffee-react execjs middleman-core (>= 3.0) react-source (~> 0.13.3) @@ -31,6 +32,8 @@ GEM ffi (~> 1.0, >= 1.0.11) chunky_png (1.3.4) coderay (1.1.0) + coffee-react (3.0.1) + execjs coffee-script (2.4.1) coffee-script-source execjs diff --git a/fixtures/app/source/assets/javascripts/cjsx_component.cjsx b/fixtures/app/source/assets/javascripts/cjsx_component.cjsx new file mode 100644 index 0000000..422e10b --- /dev/null +++ b/fixtures/app/source/assets/javascripts/cjsx_component.cjsx @@ -0,0 +1,7 @@ +###* @jsx React.DOM ### + +@app.components.test = React.createClass + render: -> +
+ +
diff --git a/lib/middleman-react/cjsx/template.rb b/lib/middleman-react/cjsx/template.rb new file mode 100644 index 0000000..41f819c --- /dev/null +++ b/lib/middleman-react/cjsx/template.rb @@ -0,0 +1,35 @@ +# encoding: UTF-8 + +require 'tilt' +require 'coffee-react' + +module Middleman + module React + module CJSX + # Tilt Tempalte for handling CJSX files + class Template < Tilt::Template + self.default_mime_type = 'application/javascript' + + cattr_accessor :harmony + cattr_accessor :strip_types + + @harmony = false + @strip_types = false + + def prepare + if self.class.harmony || options.key?(:harmony) + options[:harmony] = self.class.harmony + end + if self.class.strip_types || options.key?(:stripTypes) + options[:stripTypes] = self.class.strip_types + end + end + + def evaluate(_scope, _locals, &_block) + @coffee ||= ::CoffeeReact.transform(data, options) + @output ||= ::CoffeeScript.compile @coffee + end + end + end + end +end diff --git a/lib/middleman-react/extension.rb b/lib/middleman-react/extension.rb index 32638c2..853514c 100644 --- a/lib/middleman-react/extension.rb +++ b/lib/middleman-react/extension.rb @@ -3,6 +3,7 @@ require 'middleman-core' require 'middleman-react/jsx' require 'middleman-react/jsx/template' +require 'middleman-react/cjsx/template' module Middleman module React @@ -14,11 +15,20 @@ class Extension < Middleman::Extension def initialize(app, options_hash = {}, &block) super - Middleman::React::Template.harmony = options[:harmony] - Middleman::React::Template.strip_types = options[:strip_types] + Middleman::React::JSX::Template.harmony = options[:harmony] + Middleman::React::JSX::Template.strip_types = options[:strip_types] + Middleman::React::CJSX::Template.harmony = options[:harmony] + Middleman::React::CJSX::Template.strip_types = options[:strip_types] - ::Tilt.register 'jsx', Middleman::React::Template - ::Sprockets.register_engine 'jsx', Middleman::React::Template + ::Tilt.register 'jsx', Middleman::React::JSX::Template + ::Sprockets.register_engine 'jsx', Middleman::React::JSX::Template + + ::Tilt.register 'cjsx', Middleman::React::CJSX::Template + ::Sprockets.register_engine 'cjsx', Middleman::React::CJSX::Template + end + + def after_configuration + @app.template_extensions cjsx: :js, jsx: :js end end end diff --git a/lib/middleman-react/jsx/template.rb b/lib/middleman-react/jsx/template.rb index 7a681c0..67a2810 100644 --- a/lib/middleman-react/jsx/template.rb +++ b/lib/middleman-react/jsx/template.rb @@ -4,27 +4,29 @@ module Middleman module React - # Tilt Tempalte for handling JSX files - class Template < Tilt::Template - self.default_mime_type = 'application/javascript' + module JSX + # Tilt Tempalte for handling JSX files + class Template < Tilt::Template + self.default_mime_type = 'application/javascript' - cattr_accessor :harmony - cattr_accessor :strip_types + cattr_accessor :harmony + cattr_accessor :strip_types - @harmony = false - @strip_types = false + @harmony = false + @strip_types = false - def prepare - if self.class.harmony || options.key?(:harmony) - options[:harmony] = self.class.harmony + def prepare + if self.class.harmony || options.key?(:harmony) + options[:harmony] = self.class.harmony + end + if self.class.strip_types || options.key?(:stripTypes) + options[:stripTypes] = self.class.strip_types + end end - if self.class.strip_types || options.key?(:stripTypes) - options[:stripTypes] = self.class.strip_types - end - end - def evaluate(_scope, _locals, &_block) - @output ||= JSX.transform(data, options) + def evaluate(_scope, _locals, &_block) + @output ||= JSX.transform(data, options) + end end end end diff --git a/middleman-react.gemspec b/middleman-react.gemspec index 29f374d..63c80ec 100644 --- a/middleman-react.gemspec +++ b/middleman-react.gemspec @@ -19,6 +19,7 @@ Gem::Specification.new do |gem| gem.add_dependency 'middleman-core', ['>= 3.0'] gem.add_dependency 'execjs' gem.add_dependency 'react-source', '~> 0.13.3' + gem.add_dependency 'coffee-react' gem.add_development_dependency 'aruba' gem.add_development_dependency 'cane' diff --git a/spec/features/coffeescript.feature b/spec/features/coffeescript.feature index 006ca23..f8f5e10 100644 --- a/spec/features/coffeescript.feature +++ b/spec/features/coffeescript.feature @@ -26,3 +26,27 @@ Feature: Transforming JSX into Javascript when it is written in Coffeescript """ And the exit status should be 0 + + Scenario: A CJSX file + When I cd to "build" + Then the following files should exist: + | assets/javascripts/cjsx_component.js | + When I run `cat assets/javascripts/cjsx_component.js` + Then the stdout from "cat assets/javascripts/cjsx_component.js" should contain exactly: + """ + + /** @jsx React.DOM */ + + (function() { + this.app.components.test = React.createClass({ + render: function() { + return React.createElement("div", null, React.createElement(TestComponent, { + "data": this.props.someData + })); + } + }); + + }).call(this); + + """ + And the exit status should be 0