lefty
Version:
A JSX transformer for migi
260 lines (240 loc) • 9.13 kB
JavaScript
define(function(require, exports, module){'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _homunculus = require('homunculus');
var _homunculus2 = _interopRequireDefault(_homunculus);
var _InnerTree = require('./InnerTree');
var _InnerTree2 = _interopRequireDefault(_InnerTree);
var _linkage = require('./linkage');
var _linkage2 = _interopRequireDefault(_linkage);
var _ignore = require('./ignore');
var _ignore2 = _interopRequireDefault(_ignore);
var _join = require('./join');
var _join2 = _interopRequireDefault(_join);
var _join3 = require('./join2');
var _join4 = _interopRequireDefault(_join3);
var _delegate = require('./delegate');
var _delegate2 = _interopRequireDefault(_delegate);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var Token = _homunculus2.default.getClass('token', 'jsx');
var Node = _homunculus2.default.getClass('node', 'jsx');
function elem(node, opt, param) {
var res = '';
//open和selfClose逻辑复用
res += selfClose(node.first(), opt, param);
res += ',[';
var comma = false;
for (var i = 1, len = node.size(); i < len - 1; i++) {
var leaf = node.leaf(i);
switch (leaf.name()) {
case Node.JSXChild:
if (comma) {
res += ',';
comma = false;
}
res += child(leaf, opt, param);
comma = true;
break;
case Node.TOKEN:
var s = leaf.token().content();
//open和close之间的空白不能忽略
if (/^\s+$/.test(s)) {
if (leaf.prev().name() === Node.JSXOpeningElement && leaf.next().name() === Node.JSXClosingElement) {
res += '"' + s.replace(/"/g, '\\"').replace(/\n/g, '\\n\\\n') + '"';
} else {
res += s;
}
} else {
if (comma) {
res += ',';
comma = false;
}
res += '"' + s.replace(/"/g, '\\"').replace(/\n/g, '\\n\\\n') + '"';
comma = true;
}
break;
default:
if (comma) {
res += ',';
comma = false;
}
res += parse(leaf, opt, param);
comma = true;
}
}
res += '])';
if (node.last().name() === Node.JSXClosingElement) {
res += (0, _ignore2.default)(node.last(), true).res;
}
return res;
}
function selfClose(node, opt, param) {
var res = '';
var name = void 0;
var first = node.leaf(1);
if (first.isToken()) {
name = first.token().content();
} else if (first.name() === Node.JSXMemberExpression) {
name = first.first().token().content();
for (var i = 1, len = first.size(); i < len; i++) {
name += first.leaf(i).token().content();
}
}
if (/^[A-Z]/.test(name)) {
res += 'migi.createCp(';
res += name;
} else {
res += 'migi.createVd(';
res += '"' + name + '"';
}
res += ',[';
for (var _i = 2, _len = node.size(); _i < _len - 1; _i++) {
var leaf = node.leaf(_i);
if (_i !== 2) {
res += ',';
}
switch (leaf.name()) {
case Node.JSXBindAttribute:
res += attr(leaf, opt, param);
break;
case Node.JSXAttribute:
res += attr(leaf, opt, param);
break;
case Node.JSXSpreadAttribute:
res += spread(leaf);
break;
}
}
res += ']';
return res;
}
function attr(node, opt, param) {
var res = '';
var key = node.first().token().content();
var name = node.parent().leaf(1).token().content();
var isCp = /^[A-Z]/.test(name);
if (key.charAt(0) === '@') {
key = key.slice(1);
}
// 组件属性非@申明均不bind
else if (isCp && opt.isBind) {
opt.isBind = false;
}
var k = '["' + key + '"';
res += k + ',';
var v = node.last();
if (v.isToken()) {
v = v.token().content();
res += v;
} else if (/^on-?[a-zA-Z]/.test(key)) {
res += onEvent(v, opt, param);
} else {
res += child(v, opt, param, true);
}
res += ']';
return res;
}
function onEvent(node, opt, param) {
return (0, _delegate2.default)(node, param);
}
function spread(node) {
return (0, _join2.default)(node.leaf(2));
}
function child(node, opt, param, isAttr) {
var callexpr = node.leaf(1);
if (opt.isBind) {
var temp = (0, _linkage2.default)(callexpr, param, {
arrowFn: opt.arrowFn
});
var list = temp.arr;
var single = temp.single;
var bind = temp.bind;
if (list.length) {
var listener = list.length === 1 ? '"' + list[0] + '"' : JSON.stringify(list);
if (isAttr) {
var key = node.prev().prev().token().content();
if (key === 'value' || key === 'checked' || key === 'selected') {
var tag = node.parent().parent().leaf(1).token().content();
if (tag === 'input' || tag === 'select' || tag === 'option') {
var value = node.leaf(1);
// 单独值mmbexpr非运算符双向绑定,其余单向
if (value.name() === Node.MMBEXPR) {
var v = (0, _join4.default)(value);
return 'new migi.Obj(' + listener + ',()=>{return(' + new _InnerTree2.default(opt, param).parse(node).replace(/^(\s*){/, '$1').replace(/}(\s*)$/, '$1') + ')}' + (single ? ',true' : ',false') + (bind ? ',(v)=>{v!==' + v + '&&(' + v + '=v)})' : ')');
}
return 'new migi.Obj(' + listener + ',()=>{return(' + new _InnerTree2.default(opt, param).parse(node).replace(/^(\s*){/, '$1').replace(/}(\s*)$/, '$1') + ')}' + (single ? ',true' : '') + ')';
}
}
} else if (node.prev() && node.prev().name() === Node.JSXOpeningElement) {
var _key = node.prev().leaf(1).token().content();
if (_key === 'textarea') {
var _value = node.leaf(1);
if (_value.name() === Node.MMBEXPR) {
var _v = (0, _join4.default)(_value);
return 'new migi.Obj(' + listener + ',()=>{return(' + new _InnerTree2.default(opt, param).parse(node).replace(/^(\s*){/, '$1').replace(/}(\s*)$/, '$1') + ')}' + (single ? ',true' : ',false') + (bind ? ',(v)=>{v!==' + _v + '&&(' + _v + '=v)})' : ')');
}
}
}
return 'new migi.Obj(' + listener + ',()=>{return(' + new _InnerTree2.default(opt, param).parse(node).replace(/^(\s*){/, '$1').replace(/}(\s*)$/, '$1') + ')}' + (single ? ',true' : '') + ')';
}
}
// Obj中再次出现的:input的value还需要添加Obj
else if (opt.isInBind) {
if (isAttr) {
var _key2 = node.prev().prev().token().content();
if (_key2 === 'value') {
var _tag = node.parent().parent().leaf(1).token().content();
if (_tag === 'input' || _tag === 'select') {
var _temp = (0, _linkage2.default)(callexpr, param, {
arrowFn: opt.arrowFn
});
var _list = _temp.arr;
var _bind = _temp.bind;
if (_list.length) {
var _value2 = node.leaf(1);
var _listener = _list.length === 1 ? '"' + _list[0] + '"' : JSON.stringify(_list);
if (_value2.name() === Node.MMBEXPR) {
var _v2 = (0, _join4.default)(_value2);
return 'new migi.Obj(' + _listener + ',()=>{return(' + new _InnerTree2.default(opt, param).parse(node).replace(/^(\s*){/, '$1').replace(/}(\s*)$/, '$1') + ')}' + ',false' + (_bind ? ',(v)=>{v!==' + _v2 + '&&(' + _v2 + '=v)})' : ')');
}
return 'new migi.Obj(' + _listener + ',()=>{return(' + new _InnerTree2.default(opt, param).parse(node).replace(/^(\s*){/, '$1').replace(/}(\s*)$/, '$1') + ')})';
}
}
}
} else if (node.prev() && node.prev().name() === Node.JSXOpeningElement) {
var _key3 = node.prev().leaf(1).token().content();
if (_key3 === 'textarea') {
var _temp2 = (0, _linkage2.default)(callexpr, param, {
arrowFn: opt.arrowFn
});
var _list2 = _temp2.arr;
var _bind2 = _temp2.bind;
if (_list2.length) {
var _value3 = node.leaf(1);
var _listener2 = _list2.length === 1 ? '"' + _list2[0] + '"' : JSON.stringify(_list2);
if (_value3.name() === Node.MMBEXPR) {
var _v3 = (0, _join4.default)(_value3);
return 'new migi.Obj(' + _listener2 + ',()=>{return(' + new _InnerTree2.default(opt, param).parse(node).replace(/^(\s*){/, '$1').replace(/}(\s*)$/, '$1') + ')}' + ',false' + (_bind2 ? ',(v)=>{v!==' + _v3 + '&&(' + _v3 + '=v)})' : ')');
}
return 'new migi.Obj(' + _listener2 + ',()=>{return(' + new _InnerTree2.default(opt, param).parse(node).replace(/^(\s*){/, '$1').replace(/}(\s*)$/, '$1') + ')})';
}
}
}
}
return new _InnerTree2.default(opt, param).parse(node).replace(/^(\s*){/, '$1').replace(/}(\s*)$/, '$1');
}
function parse(node, opt, param) {
var res = '';
switch (node.name()) {
case Node.JSXElement:
res += elem(node, opt, param);
break;
case Node.JSXSelfClosingElement:
res += selfClose(node, opt, param);
res += ')';
break;
}
return res;
}
exports.default = parse;});