Add harmony transform support in browser (Fixes GH-1420)

I implemented this by checking for `type="text/jsx;harmony"`, since this
has a bit of a cleaner implementation rather than parsing a JSON object
out of a data attribute. If in the future there are other options to
pass, it would make sense to move to a system like that.

Along with adding support, there is also a new example added that's
the basic-jsx example with Harmony syntax.
This commit is contained in:
remixz
2014-05-13 22:07:02 -07:00
parent b66202eb98
commit 65c258a7b7
2 changed files with 67 additions and 9 deletions
+51
View File
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-type' content='text/html; charset=utf-8'>
<title>Basic Example with JSX with Harmony</title>
<link rel="stylesheet" href="../shared/css/base.css" />
</head>
<body>
<h1>Basic Example with JSX with Harmony</h1>
<div id="container">
<p>
To install React, follow the instructions on
<a href="http://www.github.com/facebook/react/">GitHub</a>.
</p>
<p>
If you can see this, React is not working right.
If you checked out the source from GitHub make sure to run <code>grunt</code>.
</p>
</div>
<h4>Example Details</h4>
<p>This is written with JSX with Harmony (ES6) syntax and transformed in the browser.<p>
<p>
Learn more about React at
<a href="http://facebook.github.io/react" target="_blank">facebook.github.io/react</a>.
</p>
<script src="../../build/react.js"></script>
<script src="../../build/JSXTransformer.js"></script>
<script type="text/jsx;harmony">
/**
* @jsx React.DOM
*/
var ExampleApplication = React.createClass({
render() {
var elapsed = Math.round(this.props.elapsed / 100);
var seconds = elapsed / 10 + (elapsed % 10 ? '' : '.0' );
var message =
`React has been successfully running for ${seconds} seconds.`;
return <p>{message}</p>;
}
});
var start = new Date().getTime();
setInterval(() => {
React.renderComponent(
<ExampleApplication elapsed={new Date().getTime() - start} />,
document.getElementById('container')
);
}, 50);
</script>
</body>
</html>
+16 -9
View File
@@ -89,12 +89,12 @@ var createSourceCodeErrorMessage = function(code, e) {
return message;
};
var transformCode = function(code, source) {
var transformCode = function(code, source, options) {
var jsx = docblock.parseAsObject(docblock.extract(code)).jsx;
if (jsx) {
try {
var transformed = transformReact(code);
var transformed = transformReact(code, options);
} catch(e) {
e.message += '\n at ';
if (source) {
@@ -137,13 +137,13 @@ var transformCode = function(code, source) {
}
};
var run = exports.run = function(code, source) {
var run = exports.run = function(code, source, options) {
var scriptEl = document.createElement('script');
scriptEl.text = transformCode(code, source);
scriptEl.text = transformCode(code, source, options);
headEl.appendChild(scriptEl);
};
var load = exports.load = function(url, callback) {
var load = exports.load = function(url, callback, options) {
var xhr;
xhr = window.ActiveXObject ? new window.ActiveXObject('Microsoft.XMLHTTP')
: new XMLHttpRequest();
@@ -157,7 +157,7 @@ var load = exports.load = function(url, callback) {
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 0 || xhr.status === 200) {
run(xhr.responseText, url);
run(xhr.responseText, url, options);
} else {
throw new Error("Could not load " + url);
}
@@ -175,7 +175,7 @@ runScripts = function() {
// Array.prototype.slice cannot be used on NodeList on IE8
var jsxScripts = [];
for (var i = 0; i < scripts.length; i++) {
if (scripts.item(i).type === 'text/jsx') {
if (scripts.item(i).type.indexOf('text/jsx') !== -1) {
jsxScripts.push(scripts.item(i));
}
}
@@ -183,10 +183,17 @@ runScripts = function() {
console.warn("You are using the in-browser JSX transformer. Be sure to precompile your JSX for production - http://facebook.github.io/react/docs/tooling-integration.html#jsx");
jsxScripts.forEach(function(script) {
var options;
if (script.type.indexOf('harmony') !== -1) {
options = {
harmony: true
};
}
if (script.src) {
load(script.src);
load(script.src, null, options);
} else {
run(script.innerHTML, null);
run(script.innerHTML, null, options);
}
});
};