Skip to content

Commit 1f31073

Browse files
[CS2] JSX documentation, Try CoffeeScript improvements (#4583)
* Update browser compiler * Argument parsing tests require CommonJS environment * JSX section in the docs * Breaking change note for < and > operators * Fix JSX example * Try CoffeeScript improvements: set the hash automatically, remove ‘link’ button, automatically save code in localStorage * Fix the code editors’ handling of tab-indented code * Fix JSX example to work with React * Compiled, not rendered
1 parent a3a1fb0 commit 1f31073

File tree

13 files changed

+200
-47
lines changed

13 files changed

+200
-47
lines changed

docs/v2/browser-compiler/coffeescript.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/v2/index.html

Lines changed: 112 additions & 23 deletions
Large diffs are not rendered by default.

documentation/examples/jsx.coffee

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
renderStarRating = ({ rating, maxStars }) ->
2+
<aside title={"Rating: #{rating} of #{maxStars} stars"}>
3+
{for wholeStar in [0...Math.floor(rating)]
4+
<Star className="wholeStar" key={wholeStar} />}
5+
{if rating % 1 isnt 0
6+
<Star className="halfStar" />}
7+
{for emptyStar in [Math.ceil(rating)...maxStars]
8+
<Star className="emptyStar" key={emptyStar} />}
9+
</aside>

documentation/images/link.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### JSX and the `<` and `>` Operators
2+
3+
With the addition of [JSX](#jsx), the `<` and `>` characters serve as both the “less than” and “greater than” operators and as the delimiters for XML tags, like `<div>`. For best results, in general you should always wrap the operators in spaces to distinguish them from XML tags: `i < len`, not `i<len`. The compiler tries to be forgiving when it can be sure what you intend, but always putting spaces around the “less than” and “greater than” operators will remove ambiguity.

documentation/sections/coffeescript_2.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ The biggest change in CoffeeScript 2 is that now the CoffeeScript compiler produ
66

77
Support for ES2015+ syntax is important to ensure compatibility with frameworks that assume ES2015. Now that CoffeeScript compiles classes to the ES `class` keyword, it’s possible to `extend` an ES class; that wasn’t possible in CoffeeScript 1. Parity in how language features work is also important on its own; CoffeeScript “is just JavaScript,” and so things like [function parameter default values](#breaking-changes-default-values) should behave the same in CoffeeScript as in JavaScript.
88

9-
Many ES2015+ features have been backported to CoffeeScript 1.11 and 1.12, including [modules](#modules), [`for…of`](#generator-iteration), and [tagged template literals](#tagged-template-literals). One major new feature unique to CoffeeScript 2 is support for ES2017’s [async functions](#async-functions). More details are in the [changelog](#changelog).
9+
Many ES2015+ features have been backported to CoffeeScript 1.11 and 1.12, including [modules](#modules), [`for…of`](#generator-iteration), and [tagged template literals](#tagged-template-literals). Major new features unique to CoffeeScript 2 are support for ES2017’s [async functions](#async-functions) and for [JSX](#jsx). More details are in the [changelog](#changelog).
1010

1111
There are very few [breaking changes from CoffeeScript 1.x to 2](#breaking-changes); we hope the upgrade process is smooth for most projects.
1212

documentation/sections/jsx.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
## JSX
2+
3+
[JSX](https://facebook.github.io/react/docs/introducing-jsx.html) is JavaScript containing interspersed XML elements. While conceived for [React](https://facebook.github.io/react/), it is not specific to any particular library or framework.
4+
5+
CoffeeScript supports interspersed XML elements, without the need for separate plugins or special settings. The XML elements will be compiled as such, outputting JSX that could be parsed like any normal JSX file, for example by [Babel with the React JSX transform](https://babeljs.io/docs/plugins/transform-react-jsx/). CoffeeScript does _not_ output `React.createElement` calls or any code specific to React or any other framework. It is up to you to attach another step in your build chain to convert this JSX to whatever function calls you wish the XML elements to compile to.
6+
7+
Just like in JSX and HTML, denote XML tags using `<` and `>`. You can interpolate CoffeeScript code inside a tag using `{` and `}`. To avoid compiler errors, when using `<` and `>` to mean “less than” or “greater than,” you should wrap the operators in spaces to distinguish them from XML tags. So `i < len`, not `i<len`. The compiler tries to be forgiving when it can be sure what you intend, but always putting spaces around the “less than” and “greater than” operators will remove ambiguity.
8+
9+
```
10+
codeFor('jsx')
11+
```
12+
13+
Older plugins or forks of CoffeeScript supported JSX syntax and referred to it as CSX or CJSX. They also often used a `.cjsx` file extension, but this is no longer necessary; regalar `.coffee` will do.

documentation/sections/usage.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ Once installed, you should have access to the `coffee` command, which can execut
4040

4141
CoffeeScript 2 outputs the latest ES2015+ syntax. If you’re looking for a single tool that takes CoffeeScript input and generates JavaScript output that runs in any JavaScript runtime, assuming you opt out of certain newer features, stick to [CoffeeScript 1.x](/v1/). CoffeeScript 2 [breaks compatibility](#breaking-changes) with certain CoffeeScript 1.x features in order to conform with the ES2015+ specifications, and generate more idiomatic output (a CoffeeScript `=>` becomes an ES `=>`; a CoffeeScript `class` becomes an ES `class`; and so on).
4242

43-
Since the CoffeeScript 2 compiler outputs ES2015+ syntax, it is your responsibility to either ensure that your target JavaScript runtime(s) support all these features, or that you pass the output through another transpiler like [Babel](http://babeljs.io/), [Rollup](https://github.com/rollup/rollup) or [Traceur Compiler](https://github.com/google/traceur-compiler). In general, [CoffeeScript 2’s output is supported as is by Node.js 7.6+](http://node.green/), except for modules which require transpilation.
43+
Since the CoffeeScript 2 compiler outputs ES2015+ syntax, it is your responsibility to either ensure that your target JavaScript runtime(s) support all these features, or that you pass the output through another transpiler like [Babel](http://babeljs.io/), [Rollup](https://github.com/rollup/rollup) or [Traceur Compiler](https://github.com/google/traceur-compiler). In general, [CoffeeScript 2’s output is supported as is by Node.js 7.6+](http://node.green/), except for modules and JSX which require transpilation.
4444

4545
There are many great task runners for setting up JavaScript build chains, such as [Gulp](http://gulpjs.com/), [Webpack](https://webpack.github.io/), [Grunt](https://gruntjs.com/) and [Broccoli](http://broccolijs.com/). If you’re looking for a very minimal solution to get started, you can use [babel-preset-env](https://babeljs.io/docs/plugins/preset-env/) and the command line:
4646

4747
```bash
4848
npm install --global coffeescript@next
4949
npm install --save-dev coffeescript@next babel-cli babel-preset-env
50-
coffee -p *.coffee | babel --presets env > app.js
50+
coffee --print *.coffee | babel --presets env > app.js
5151
```
5252

5353
### Node.js

documentation/v2/body.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@
106106
<section id="embedded">
107107
<%= htmlFor('embedded') %>
108108
</section>
109+
<section id="jsx">
110+
<%= htmlFor('jsx') %>
111+
</section>
109112
</section>
110113
<section id="literate">
111114
<%= htmlFor('literate') %>
@@ -166,6 +169,9 @@
166169
<section id="breaking-changes-super-extends">
167170
<%= htmlFor('breaking_changes_super_extends') %>
168171
</section>
172+
<section id="breaking-changes-jsx-and-the-less-than-and-greater-than-operators">
173+
<%= htmlFor('breaking_changes_jsx_and_the_less_than_and_greater_than_operators') %>
174+
</section>
169175
<section id="breaking-changes-literate-coffeescript">
170176
<%= htmlFor('breaking_changes_literate_coffeescript') %>
171177
</section>

documentation/v2/docs.coffee

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,6 @@ $(document).ready ->
1313
window.location = event.target.href
1414
, 260 # Wait for the sidebar to slide away before navigating
1515

16-
17-
# Try CoffeeScript
18-
toggleTry = ->
19-
$('#try, #try-link').toggleClass 'active'
20-
closeTry = ->
21-
$('#try, #try-link').removeClass 'active'
22-
23-
$('[data-toggle="try"]').click toggleTry
24-
$('[data-close="try"]').click closeTry
25-
26-
2716
# Initialize Scrollspy for sidebar navigation; http://v4-alpha.getbootstrap.com/components/scrollspy/
2817
# See also http://www.codingeverything.com/2014/02/BootstrapDocsSideBar.html and http://jsfiddle.net/KyleMit/v6zhz/
2918
$('body').scrollspy
@@ -60,20 +49,46 @@ $(document).ready ->
6049
viewportMargin: Infinity
6150

6251
# Whenever the user edits the CoffeeScript side of a code example, update the JavaScript output
52+
# If the editor is Try CoffeeScript, also update the hash and save this code in localStorage
6353
if mode is 'coffeescript'
6454
pending = null
6555
editor.on 'change', (instance, change) ->
6656
clearTimeout pending
6757
pending = setTimeout ->
6858
lastCompilationStartTime = Date.now()
6959
try
70-
output = CoffeeScript.compile editor.getValue(), bare: yes
60+
coffee = editor.getValue()
61+
if index is 0 and $('#try').hasClass('active') # If this is the editor in Try CoffeeScript and it’s still visible
62+
# Update the hash with the current code
63+
link = "try:#{encodeURIComponent coffee}"
64+
window.history.pushState {}, 'CoffeeScript', "#{location.href.split('#')[0]}##{link}"
65+
# Save this to the user’s localStorage
66+
try
67+
if window.localStorage?
68+
window.localStorage.setItem 'tryCoffeeScriptCode', coffee
69+
catch exception
70+
output = CoffeeScript.compile coffee, bare: yes
7171
lastCompilationElapsedTime = Math.max(200, Date.now() - lastCompilationStartTime)
7272
catch exception
7373
output = "#{exception}"
7474
editors[index + 1].setValue output
7575
, lastCompilationElapsedTime
7676

77+
# Fix the code editors’ handling of tab-indented code
78+
editor.addKeyMap
79+
'Tab': (cm) ->
80+
if cm.somethingSelected()
81+
cm.indentSelection 'add'
82+
else if /^\t/m.test cm.getValue()
83+
# If any lines start with a tab, treat this as tab-indented code
84+
cm.execCommand 'insertTab'
85+
else
86+
cm.execCommand 'insertSoftTab'
87+
'Shift-Tab': (cm) ->
88+
cm.indentSelection 'subtract'
89+
'Enter': (cm) ->
90+
cm.options.indentWithTabs = /^\t/m.test cm.getValue()
91+
cm.execCommand 'newlineAndIndent'
7792

7893
# Handle the code example buttons
7994
$('[data-action="run-code-example"]').click ->
@@ -83,17 +98,27 @@ $(document).ready ->
8398
js = "#{js}\nalert(#{unescape run});" unless run is yes
8499
eval js
85100

86-
$('[data-action="link"]').click ->
87-
index = $("##{$(@).data('example')}-coffee").data 'index'
88-
coffee = editors[index].getValue()
89-
link = "try:#{encodeURIComponent coffee}"
90-
window.history.pushState {}, 'CoffeeScript', "#{location.href.split('#')[0]}##{link}"
101+
102+
# Try CoffeeScript
103+
toggleTry = (checkLocalStorage = no) ->
104+
if checkLocalStorage and window.localStorage?
105+
try
106+
coffee = window.localStorage.getItem 'tryCoffeeScriptCode'
107+
if coffee?
108+
editors[0].setValue coffee
109+
catch exception
110+
$('#try, #try-link').toggleClass 'active'
111+
closeTry = ->
112+
$('#try, #try-link').removeClass 'active'
113+
114+
$('[data-toggle="try"]').click toggleTry
115+
$('[data-close="try"]').click closeTry
91116

92117

93118
# Configure the initial state
94119
if window.location.hash?
95120
if window.location.hash is '#try'
96-
toggleTry()
121+
toggleTry yes
97122
else if window.location.hash.indexOf('#try') is 0
98123
editors[0].setValue decodeURIComponent window.location.hash[5..]
99124
toggleTry()

0 commit comments

Comments
 (0)