Created
March 2, 2015 18:43
-
-
Save Naddiseo/800aab5c780d9440ba70 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* global require, module */ | |
var libname = 'babel/lib/babel'; | |
var t = require(libname + '/types'); | |
var transform = require(libname + '/transformation'); | |
var Transformer = require(libname + '/transformation/transformer'); | |
var File = require(libname + '/transformation/file'); | |
function isString(s) { return {}.toString.call(s) === '[object String]'; } | |
var isStringLiteral = function (node) { | |
return t.isLiteral(node) && isString(node.value); | |
}; | |
var flatten = function (args) { | |
var flattened = []; | |
var last; | |
for (var i = 0; i < args.length; i++) { | |
var arg = args[i]; | |
if (isStringLiteral(arg) && isStringLiteral(last)) { | |
last.value += arg.value; | |
} else { | |
last = arg; | |
flattened.push(arg); | |
} | |
} | |
return flattened; | |
}; | |
var cleanJSXElementLiteralChild = function (child, args) { | |
var lines = child.value.split(/\r\n|\n|\r/); | |
var lastNonEmptyLine = 0; | |
var i; | |
for (i = 0; i < lines.length; i++) { | |
if (lines[i].match(/[^ \t]/)) { | |
lastNonEmptyLine = i; | |
} | |
} | |
for (i = 0; i < lines.length; i++) { | |
var line = lines[i]; | |
var isFirstLine = i === 0; | |
var isLastLine = i === lines.length - 1; | |
var isLastNonEmptyLine = i === lastNonEmptyLine; | |
// replace rendered whitespace tabs with spaces | |
var trimmedLine = line.replace(/\t/g, " "); | |
// trim whitespace touching a newline | |
if (!isFirstLine) { | |
trimmedLine = trimmedLine.replace(/^[ ]+/, ""); | |
} | |
// trim whitespace touching an endline | |
if (!isLastLine) { | |
trimmedLine = trimmedLine.replace(/[ ]+$/, ""); | |
} | |
if (trimmedLine) { | |
if (!isLastNonEmptyLine) { | |
trimmedLine += " "; | |
} | |
args.push(t.literal(trimmedLine)); | |
} | |
} | |
}; | |
var buildJSXOpeningElementAttributes = function (attribs, file) { | |
var _props = []; | |
var objs = []; | |
var pushProps = function () { | |
if (!_props.length) return; | |
objs.push(t.objectExpression(_props)); | |
_props = []; | |
}; | |
while (attribs.length) { | |
var prop = attribs.shift(); | |
if (t.isJSXSpreadAttribute(prop)) { | |
pushProps(); | |
objs.push(prop.argument); | |
} else { | |
_props.push(prop); | |
} | |
} | |
pushProps(); | |
if (objs.length === 1) { | |
// only one object | |
attribs = objs[0]; | |
} else { | |
// looks like we have multiple objects | |
if (!t.isObjectExpression(objs[0])) { | |
objs.unshift(t.objectExpression([])); | |
} | |
// spread it | |
attribs = t.callExpression( | |
//t.memberExpression(t.identifier('Object'), t.identifier('assign')), | |
file.addHelper('extends'), | |
objs | |
); | |
} | |
return attribs; | |
}; | |
var msxTR = { | |
check: function (node) { | |
return t.isJSX(node); | |
}, | |
JSXIdentifier: function (node, parent) { | |
if (node.name === "this" && t.isReferenced(node, parent)) { | |
return t.thisExpression(); | |
} | |
else if (t.isIdentifier(node.name)) { | |
node.type = "Identifier"; | |
} | |
else { | |
return t.literal(node.name); | |
} | |
}, | |
JSXEmptyExpression: function () { | |
return; | |
}, | |
JSXNamespacedName: function (node, parent, file) { | |
throw file.errorWithNode(node, "Namespace tags are not supported. ReactJSX is not XML."); | |
}, | |
JSXMemberExpression: { | |
exit: function (node) { | |
node.computed = t.isLiteral(node.property); | |
node.type = "MemberExpression"; | |
} | |
}, | |
JSXExpressionContainer: function (node) { | |
return node.expression; | |
}, | |
JSXAttribute: { | |
exit: function (node) { | |
var value = node.value || t.literal(true); | |
if (node.name) { | |
if (t.isLiteral(node.name) && node.name.value === 'class') { | |
node.name = t.literal('className'); | |
} | |
} | |
return t.inherits(t.property("init", node.name, value), node); | |
} | |
}, | |
JSXOpeningElement: { | |
exit: function (node, parent, scope, file) { | |
var tagExpr = node.name; | |
var props = []; | |
var tagName = t.isIdentifier(tagExpr) ? tagExpr.name : (t.isLiteral(tagExpr) ? tagExpr.value : 'UNKNOWN'); | |
props.push(t.property('init', t.literal('tag'), t.literal(tagName))); | |
var attribs = node.attributes; | |
if (attribs.length) { | |
attribs = buildJSXOpeningElementAttributes(attribs, file); | |
} else { | |
attribs = t.literal(null); | |
} | |
props.push(t.property('init', t.literal('attrs'), attribs)); | |
return t.inherits(t.objectExpression(props), node); | |
} | |
}, | |
JSXElement: { | |
exit: function (node) { | |
var objExpr = node.openingElement; | |
var children = []; | |
for (var i = 0; i < node.children.length; i++) { | |
var child = node.children[i]; | |
if (t.isLiteral(child) && typeof child.value === "string") { | |
cleanJSXElementLiteralChild(child, children); | |
continue; | |
} else if (t.isJSXEmptyExpression(child)) { | |
continue; | |
} | |
children.push(child); | |
} | |
children = flatten(children); | |
objExpr.properties.push( | |
t.property('init', t.literal("children"), t.arrayExpression(children)) | |
); | |
return t.inherits(objExpr, node); | |
} | |
} | |
}; | |
module.exports = function (source, map) { | |
if (this.cacheable) { | |
this.cacheable(); | |
} | |
transform.transformers.msx = new Transformer('msx', msxTR); | |
var result = require('babel').transform(source, { | |
whitelist: 'msx', | |
}); | |
transform.transformers.msx = null; | |
this.callback(null, result.code, map); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function inner(item) { | |
return <a>{ item }</a>; | |
} | |
function View(ctrl) { | |
return <div> | |
{( for (item of ctrl.getList()) inner(item) )} | |
</div>; | |
} | |
class Ctrl { | |
*getList() { | |
yield 1; | |
yield 2; | |
} | |
} | |
var ctrl = new Ctrl(); | |
export default function() { | |
return View(ctrl); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// run with webpack --config webpackconf.js | |
var loaderOpts = { | |
modules: 'common', | |
blacklist: ['react', 'flow'], | |
optional: ['runtime', 'utility.deadCodeElimination', 'regenerator'], | |
loose: ['es6.classes',], | |
format: { | |
indent: { | |
style: '\t' | |
} | |
}, | |
experimental: true | |
}; | |
module.exports = { | |
context: __dirname, | |
target: 'web', | |
entry: './test.jsx', | |
output: { | |
path: __dirname, | |
filename: './test.out.js' | |
}, | |
module: { | |
loaders: [ | |
{ test: /^.*?\.jsx$/, loader: __dirname + '/msx_loader'}, | |
{ test: /^.*?\.(js|jsx)$/, loader: 'babel-loader?' + JSON.stringify(loaderOpts)}, | |
] | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment