add jsx and react transformer
This commit is contained in:
parent
531ea91a07
commit
f06901ac05
@ -94,6 +94,9 @@ transform.transformers = {
|
||||
unicodeRegex: require("./transformers/unicode-regex"),
|
||||
generators: require("./transformers/generators"),
|
||||
|
||||
react: require("./transformers/react"),
|
||||
jsx: require("./transformers/jsx"),
|
||||
|
||||
_aliasFunctions: require("./transformers/_alias-functions"),
|
||||
_blockHoist: require("./transformers/_block-hoist")
|
||||
};
|
||||
|
||||
99
lib/6to5/transformers/jsx/index.js
Normal file
99
lib/6to5/transformers/jsx/index.js
Normal file
@ -0,0 +1,99 @@
|
||||
// Based upon the excellent jsx-transpiler by Ingvar Stepanyan (RReverser)
|
||||
// https://github.com/RReverser/jsx-transpiler
|
||||
|
||||
var esutils = require("esutils");
|
||||
var b = require("recast").types.builders;
|
||||
var _ = require("lodash");
|
||||
|
||||
var JSX_ANNOTATION_REGEX = /^\*\s*@jsx\s+([^\s]+)/;
|
||||
var KNOWN_TAGS = require("./known-tags");
|
||||
|
||||
exports.Program = function (node, parent, file) {
|
||||
var jsx = "React.DOM";
|
||||
|
||||
// looking for namespace annotation
|
||||
_.each(node.comments, function (comment) {
|
||||
if (!comment.possiblyLeading) return;
|
||||
|
||||
var matches = JSX_ANNOTATION_REGEX.exec(comment.value);
|
||||
if (matches) jsx = matches[1];
|
||||
});
|
||||
|
||||
// prebuilding AST node
|
||||
file.jsx = jsx.split(".").map(b.identifier).reduce(function (object, property) {
|
||||
return b.memberExpression(object, property, false);
|
||||
});
|
||||
};
|
||||
|
||||
exports.XJSIdentifier = function (node) {
|
||||
if (esutils.keyword.isIdentifierName(node.name)) {
|
||||
node.type = "Identifier";
|
||||
} else {
|
||||
return b.literal(node.name);
|
||||
}
|
||||
};
|
||||
|
||||
exports.XJSNamespacedName = function () {
|
||||
throw new Error("Namespace tags are not supported. ReactJSX is not XML.");
|
||||
};
|
||||
|
||||
exports.XJSMemberExpression = {
|
||||
exit: function (node) {
|
||||
node.computed = node.property.type === "Literal";
|
||||
node.type = "MemberExpression";
|
||||
}
|
||||
};
|
||||
|
||||
exports.XJSEmptyExpression = function (node) {
|
||||
node.value = null;
|
||||
node.type = "Literal";
|
||||
};
|
||||
|
||||
exports.XJSExpressionContainer = function (node) {
|
||||
return node.expression;
|
||||
};
|
||||
|
||||
exports.XJSAttribute = {
|
||||
exit: function (node) {
|
||||
var value = node.value || b.literal(true);
|
||||
var propNode = b.property("init", node.name, value);
|
||||
propNode.loc = node.loc;
|
||||
return propNode;
|
||||
}
|
||||
};
|
||||
|
||||
exports.XJSOpeningElement = {
|
||||
exit: function (node, parent, file) {
|
||||
var tagExpr = node.name;
|
||||
|
||||
if (_.contains(KNOWN_TAGS, tagExpr.name)) {
|
||||
tagExpr = b.memberExpression(file.jsx, tagExpr, false);
|
||||
}
|
||||
|
||||
var props = node.attributes;
|
||||
if (props.length) {
|
||||
props = b.objectExpression(props);
|
||||
} else {
|
||||
props = b.literal(null);
|
||||
}
|
||||
|
||||
return b.callExpression(tagExpr, [props]);
|
||||
}
|
||||
};
|
||||
|
||||
exports.XJSElement = {
|
||||
exit: function (node) {
|
||||
var callExpr = node.openingElement;
|
||||
var children = node.children;
|
||||
var args = callExpr.arguments;
|
||||
|
||||
switch (children.length) {
|
||||
case 0: break;
|
||||
case 1: args.push(children[0]); break;
|
||||
default: args.push(b.arrayExpression(children));
|
||||
}
|
||||
|
||||
callExpr.loc = node.loc;
|
||||
return callExpr;
|
||||
}
|
||||
};
|
||||
132
lib/6to5/transformers/jsx/known-tags.json
Normal file
132
lib/6to5/transformers/jsx/known-tags.json
Normal file
@ -0,0 +1,132 @@
|
||||
[
|
||||
"a",
|
||||
"abbr",
|
||||
"address",
|
||||
"applet",
|
||||
"area",
|
||||
"article",
|
||||
"aside",
|
||||
"audio",
|
||||
"b",
|
||||
"base",
|
||||
"bdi",
|
||||
"bdo",
|
||||
"big",
|
||||
"blockquote",
|
||||
"body",
|
||||
"br",
|
||||
"button",
|
||||
"canvas",
|
||||
"caption",
|
||||
"circle",
|
||||
"cite",
|
||||
"code",
|
||||
"col",
|
||||
"colgroup",
|
||||
"command",
|
||||
"data",
|
||||
"datalist",
|
||||
"dd",
|
||||
"defs",
|
||||
"del",
|
||||
"details",
|
||||
"dfn",
|
||||
"dialog",
|
||||
"div",
|
||||
"dl",
|
||||
"dt",
|
||||
"ellipse",
|
||||
"em",
|
||||
"embed",
|
||||
"fieldset",
|
||||
"figcaption",
|
||||
"figure",
|
||||
"footer",
|
||||
"form",
|
||||
"g",
|
||||
"h1",
|
||||
"h2",
|
||||
"h3",
|
||||
"h4",
|
||||
"h5",
|
||||
"h6",
|
||||
"head",
|
||||
"header",
|
||||
"hgroup",
|
||||
"hr",
|
||||
"html",
|
||||
"i",
|
||||
"iframe",
|
||||
"img",
|
||||
"input",
|
||||
"ins",
|
||||
"kbd",
|
||||
"keygen",
|
||||
"label",
|
||||
"legend",
|
||||
"li",
|
||||
"line",
|
||||
"linearGradient",
|
||||
"link",
|
||||
"main",
|
||||
"map",
|
||||
"mark",
|
||||
"marquee",
|
||||
"menu",
|
||||
"menuitem",
|
||||
"meta",
|
||||
"meter",
|
||||
"nav",
|
||||
"noscript",
|
||||
"object",
|
||||
"ol",
|
||||
"optgroup",
|
||||
"option",
|
||||
"output",
|
||||
"p",
|
||||
"param",
|
||||
"path",
|
||||
"polygon",
|
||||
"polyline",
|
||||
"pre",
|
||||
"progress",
|
||||
"q",
|
||||
"radialGradient",
|
||||
"rect",
|
||||
"rp",
|
||||
"rt",
|
||||
"ruby",
|
||||
"s",
|
||||
"samp",
|
||||
"script",
|
||||
"section",
|
||||
"select",
|
||||
"small",
|
||||
"source",
|
||||
"span",
|
||||
"stop",
|
||||
"strong",
|
||||
"style",
|
||||
"sub",
|
||||
"summary",
|
||||
"sup",
|
||||
"svg",
|
||||
"table",
|
||||
"tbody",
|
||||
"td",
|
||||
"text",
|
||||
"textarea",
|
||||
"tfoot",
|
||||
"th",
|
||||
"thead",
|
||||
"time",
|
||||
"title",
|
||||
"tr",
|
||||
"track",
|
||||
"tspan",
|
||||
"u",
|
||||
"ul",
|
||||
"var",
|
||||
"video",
|
||||
"wbr"
|
||||
]
|
||||
0
lib/6to5/transformers/react.js
vendored
Normal file
0
lib/6to5/transformers/react.js
vendored
Normal file
@ -45,7 +45,8 @@
|
||||
"source-map": "0.1.40",
|
||||
"regenerator": "0.6.7",
|
||||
"chokidar": "^0.9.0",
|
||||
"source-map-support": "^0.2.7"
|
||||
"source-map-support": "^0.2.7",
|
||||
"esutils": "^1.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"es6-transpiler": "0.7.17",
|
||||
|
||||
3
test/fixtures/syntax/jsx/annotation/actual.js
vendored
Normal file
3
test/fixtures/syntax/jsx/annotation/actual.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/** @jsx CUSTOM_DOM */
|
||||
|
||||
<a></a>
|
||||
3
test/fixtures/syntax/jsx/annotation/expected.js
vendored
Normal file
3
test/fixtures/syntax/jsx/annotation/expected.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/** @jsx CUSTOM_DOM */
|
||||
|
||||
CUSTOM_DOM.a(null);
|
||||
1
test/fixtures/syntax/jsx/empty/actual.js
vendored
Normal file
1
test/fixtures/syntax/jsx/empty/actual.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
<x>{}</x>
|
||||
1
test/fixtures/syntax/jsx/empty/expected.js
vendored
Normal file
1
test/fixtures/syntax/jsx/empty/expected.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
x(null, null);
|
||||
2
test/fixtures/syntax/jsx/everything/actual.js
vendored
Normal file
2
test/fixtures/syntax/jsx/everything/actual.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
<X data-prop={x ? <Y prop={2} /> : <Z>
|
||||
</Z>}></X>
|
||||
3
test/fixtures/syntax/jsx/everything/expected.js
vendored
Normal file
3
test/fixtures/syntax/jsx/everything/expected.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
X({
|
||||
"data-prop": x ? Y({ prop: 2 }) : Z(null, "\n")
|
||||
});
|
||||
5
test/fixtures/syntax/jsx/expressions/actual.js
vendored
Normal file
5
test/fixtures/syntax/jsx/expressions/actual.js
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
(<X>{a}</X>);
|
||||
|
||||
(<X>{a} {b}</X>);
|
||||
|
||||
(<X prop={a} yes></X>);
|
||||
3
test/fixtures/syntax/jsx/expressions/expected.js
vendored
Normal file
3
test/fixtures/syntax/jsx/expressions/expected.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
X(null, a);
|
||||
X(null, [a, ' ', b]);
|
||||
X({ prop: a, yes: true });
|
||||
1
test/fixtures/syntax/jsx/known-tags/actual.js
vendored
Normal file
1
test/fixtures/syntax/jsx/known-tags/actual.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
<a></a>
|
||||
1
test/fixtures/syntax/jsx/known-tags/expected.js
vendored
Normal file
1
test/fixtures/syntax/jsx/known-tags/expected.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
React.DOM.a(null);
|
||||
1
test/fixtures/syntax/jsx/member-expression/actual.js
vendored
Normal file
1
test/fixtures/syntax/jsx/member-expression/actual.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
<Test.X></Test.X>
|
||||
1
test/fixtures/syntax/jsx/member-expression/expected.js
vendored
Normal file
1
test/fixtures/syntax/jsx/member-expression/expected.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
Test.X(null);
|
||||
1
test/fixtures/syntax/jsx/no-xml-namespaces/actual.js
vendored
Normal file
1
test/fixtures/syntax/jsx/no-xml-namespaces/actual.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
<Test:X></Test:X>
|
||||
3
test/fixtures/syntax/jsx/no-xml-namespaces/options.json
vendored
Normal file
3
test/fixtures/syntax/jsx/no-xml-namespaces/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"throws": "Namespace tags are not supported. ReactJSX is not XML."
|
||||
}
|
||||
3
test/fixtures/syntax/jsx/self-closing-tags/actual.js
vendored
Normal file
3
test/fixtures/syntax/jsx/self-closing-tags/actual.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
(<X />);
|
||||
|
||||
(<X prop="1" />);
|
||||
2
test/fixtures/syntax/jsx/self-closing-tags/expected.js
vendored
Normal file
2
test/fixtures/syntax/jsx/self-closing-tags/expected.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
X(null);
|
||||
X({ prop: '1' });
|
||||
1
test/fixtures/syntax/jsx/simple-tags/actual.js
vendored
Normal file
1
test/fixtures/syntax/jsx/simple-tags/actual.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
<X></X>
|
||||
1
test/fixtures/syntax/jsx/simple-tags/expected.js
vendored
Normal file
1
test/fixtures/syntax/jsx/simple-tags/expected.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
X(null);
|
||||
3
test/fixtures/syntax/jsx/tags-with-children/actual.js
vendored
Normal file
3
test/fixtures/syntax/jsx/tags-with-children/actual.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
(<X prop="2"><Y /></X>);
|
||||
|
||||
(<X prop="2"><Y /><Z /></X>);
|
||||
2
test/fixtures/syntax/jsx/tags-with-children/expected.js
vendored
Normal file
2
test/fixtures/syntax/jsx/tags-with-children/expected.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
X({ prop: '2' }, Y(null));
|
||||
X({ prop: '2' }, [Y(null), Z(null)]);
|
||||
13
test/fixtures/syntax/jsx/tags-with-literals/actual.js
vendored
Normal file
13
test/fixtures/syntax/jsx/tags-with-literals/actual.js
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
(<X> </X>);
|
||||
|
||||
(<X>
|
||||
</X>);
|
||||
|
||||
(<X>
|
||||
string
|
||||
</X>);
|
||||
|
||||
(<X>
|
||||
string
|
||||
string
|
||||
</X>);
|
||||
4
test/fixtures/syntax/jsx/tags-with-literals/expected.js
vendored
Normal file
4
test/fixtures/syntax/jsx/tags-with-literals/expected.js
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
X(null, ' ');
|
||||
X(null, '\n');
|
||||
X(null, '\n string\n');
|
||||
X(null, '\n string\n string\n ');
|
||||
Loading…
x
Reference in New Issue
Block a user