UNPKG

babel-plugin-vidom-jsx

Version:

[![Build Status](https://img.shields.io/travis/dfilatov/babel-plugin-vidom-jsx/master.svg?style=flat-square)](https://travis-ci.org/dfilatov/babel-plugin-vidom-jsx/branches) [![NPM Version](https://img.shields.io/npm/v/babel-plugin-vidom-jsx.svg?style=fla

217 lines (179 loc) 6.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = _default; var _pluginSyntaxJsx = _interopRequireDefault(require("@babel/plugin-syntax-jsx")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var VIDOM = 'vidom', ELEM_BUILDER = '_ve_'; function _default(_ref) { var types = _ref.types; var autoRequire, requireElem; function buildElemExpr(tagExpr, argsExpr) { return types.callExpression(autoRequire ? types.identifier(ELEM_BUILDER) : types.memberExpression(types.identifier(VIDOM), types.identifier('elem')), [tagExpr].concat(argsExpr)); } function buildElemArgsExpr(attrs, children, file) { var res = [], objList = []; var attrList = [], attrsExpr, keyExpr, htmlExpr, refExpr, pushAttrs = function pushAttrs() { if (!attrList.length) { return; } objList.push(types.objectExpression(attrList)); attrList = []; }; attrs.forEach(function (attr) { if (types.isJSXSpreadAttribute(attr)) { pushAttrs(); objList.push(attr.argument); } else { switch (attr.name.name) { case 'key': keyExpr = getValueExpr(attr.value); break; case 'html': htmlExpr = getValueExpr(attr.value); break; case 'ref': refExpr = getValueExpr(attr.value); break; default: attrList.push(types.objectProperty(types.stringLiteral(attr.name.name), types.isJSXExpressionContainer(attr.value) ? attr.value.expression : attr.value || types.booleanLiteral(true))); } } }); pushAttrs(); if (objList.length > 0) { if (objList.length === 1) { attrsExpr = objList[0]; } else { if (!types.isObjectExpression(objList[0])) { objList.unshift(types.objectExpression([])); } attrsExpr = types.callExpression(file.addHelper('extends'), objList); } } res.push(keyExpr || null, attrsExpr || null, htmlExpr ? htmlExpr : normalizeChildren(children), refExpr || null, htmlExpr ? types.booleanLiteral(false) : null); var notNullLen = res.length; while (notNullLen > 0) { if (res[notNullLen - 1] !== null) { break; } notNullLen--; } return (notNullLen < res.length ? res.slice(0, notNullLen) : res).map(function (expr) { return expr === null ? types.nullLiteral() : expr; }); } function getValueExpr(value) { return types.isJSXExpressionContainer(value) ? value.expression : value; } function normalizeChildren(children) { var res = children.reduce(function (acc, child) { if (types.isJSXText(child)) { child = cleanJSXText(child); if (child) { acc.push(child); } } else if (types.isJSXExpressionContainer(child)) { if (!types.isJSXEmptyExpression(child.expression)) { acc.push(child.expression); } } else { acc.push(child); } return acc; }, []); return res.length > 0 ? res.length > 1 ? types.arrayExpression(res) : res[0] : null; } function cleanJSXText(node) { var lines = node.value.split(/\r\n|\n|\r/); var lastNonEmptyLine = 0; lines.forEach(function (line, i) { if (line.match(/[^ \t]/)) { lastNonEmptyLine = i; } }); var str = ''; lines.forEach(function (line, i) { var isFirstLine = i === 0, isLastLine = i === lines.length - 1, isLastNonEmptyLine = i === lastNonEmptyLine; var trimmedLine = line.replace(/\t/g, ' '); if (!isFirstLine) { trimmedLine = trimmedLine.replace(/^[ ]+/, ''); } if (!isLastLine) { trimmedLine = trimmedLine.replace(/[ ]+$/, ''); } if (trimmedLine) { if (!isLastNonEmptyLine) { trimmedLine += ' '; } str += trimmedLine; } }); if (str) { return types.stringLiteral(str); } } function buildJSXIdentifierExpr(node, parent) { if (types.isJSXIdentifier(node)) { if (node.name === 'this' && types.isReferenced(node, parent)) { return types.thisExpression(); } if (node.name === node.name.toLowerCase() && !types.isJSXMemberExpression(parent)) { return types.stringLiteral(node.name); } node.type = 'Identifier'; return node; } if (types.isJSXMemberExpression(node)) { return types.memberExpression(buildJSXIdentifierExpr(node.object, node), buildJSXIdentifierExpr(node.property, node)); } return node; } function buildJSXFragmentExpr() { return types.stringLiteral('fragment'); } return { inherits: _pluginSyntaxJsx["default"], visitor: { JSXElement: function JSXElement(path, file) { requireElem = true; var _path$node = path.node, _path$node$openingEle = _path$node.openingElement, name = _path$node$openingEle.name, attributes = _path$node$openingEle.attributes, children = _path$node.children; path.replaceWith(buildElemExpr(buildJSXIdentifierExpr(name, path.node), buildElemArgsExpr(attributes, children, file))); }, JSXFragment: function JSXFragment(path, file) { requireElem = true; path.replaceWith(buildElemExpr(buildJSXFragmentExpr(), buildElemArgsExpr([], path.node.children, file))); }, Program: { enter: function enter(_, _ref2) { var opts = _ref2.opts; autoRequire = opts.autoRequire !== false; requireElem = false; }, exit: function exit(path) { if (!requireElem) { return; } if (autoRequire) { var importDeclaration = types.importDeclaration([types.importSpecifier(types.identifier(ELEM_BUILDER), types.identifier('elem'))], types.stringLiteral(VIDOM)); path.unshiftContainer('body', importDeclaration); } } } } }; }