-
Notifications
You must be signed in to change notification settings - Fork 7
/
index.js
56 lines (48 loc) · 1.92 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
let {DOM} = require("react");
const blacklist = ["map"];
const whitelist = Object.keys(DOM).filter(item => blacklist.indexOf(item) === -1);
export default function ({types: t}) {
const getAttributes = (props) => {
if (t.isIdentifier(props) || t.isMemberExpression(props)) {
return [t.JSXSpreadAttribute(props)];
}
return (props && props.properties || []).map(prop => {
const key = t.JSXIdentifier(prop.key.name || prop.key.value)
const value = t.isLiteral(prop.value) && (typeof prop.value.value === 'string') ? prop.value : t.JSXExpressionContainer(prop.value);
return t.JSXAttribute(key, value);
});
}
const processChildren = (children) => {
return children.map(c => {
if (t.isJSXElement(c) || t.isJSXExpressionContainer(c)) {
return c;
} else if (t.isStringLiteral(c)) {
return t.JSXText(c.value);
} else {
return t.JSXExpressionContainer(c);
}
});
}
return {
visitor: {
CallExpression: {
exit: function (path, state) {
if (whitelist.concat(state.opts.components || []).indexOf(path.node.callee.name) === -1) return;
var props = getAttributes(path.node.arguments[0]);
var children = processChildren(path.node.arguments.slice(1));
var name = t.JSXIdentifier(path.node.callee.name);
var open = t.JSXOpeningElement(name, props);
open.selfClosing = children.length === 0;
var close = children.length === 0 ? null : t.JSXClosingElement(name);
var el = t.JSXElement(open, close, children);
path.replaceWith(path.parent.type === 'ReturnStatement' ? t.ParenthesizedExpression(el) : t.ExpressionStatement(el));
}
},
ConditionalExpression: function(path) {
if (path.node.alternate.operator === 'void') {
path.replaceWith(t.LogicalExpression("&&", path.node.test, path.node.consequent));
}
}
}
}
}