"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; function _react() { const data = _interopRequireDefault(require("react")); _react = function _react() { return data; }; return data; } function _assert() { const data = _interopRequireDefault(require("assert")); _assert = function _assert() { return data; }; return data; } function _umi() { const data = require("umi"); _umi = function _umi() { return data; }; return data; } function t() { const data = _interopRequireWildcard(require("@babel/types")); t = function t() { return data; }; return data; } var _util = require("../util"); var _constants = require("../constants"); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const winPath = _umi().utils.winPath; var _default = () => { function buildGUmiUIFlag(opts) { const index = opts.index, filename = opts.filename, jsx = opts.jsx, inline = opts.inline, content = opts.content; if (jsx) { const attrs = [t().jsxAttribute(t().jsxIdentifier('filename'), t().stringLiteral(`${filename}`)), t().jsxAttribute(t().jsxIdentifier('index'), t().stringLiteral(`${index}`))]; if (inline) { attrs.push(t().jsxAttribute(t().jsxIdentifier('inline'), t().stringLiteral('true'))); } return t().jsxElement(t().jsxOpeningElement(t().jsxIdentifier('GUmiUIFlag'), attrs), t().jsxClosingElement(t().jsxIdentifier('GUmiUIFlag')), content ? [t().jsxText(content)] : [], false); } const attrs = [t().objectProperty(t().identifier('filename'), t().stringLiteral(`${filename}`)), t().objectProperty(t().identifier('index'), t().stringLiteral(`${index}`))]; if (inline) { attrs.push(t().objectProperty(t().identifier('inline'), t().stringLiteral('true'))); } return t().callExpression(t().memberExpression(t().identifier('React'), t().identifier('createElement')), [t().identifier('GUmiUIFlag'), t().objectExpression(attrs), ...(content ? [t().stringLiteral(content)] : [])]); } function addFlagToIndex(nodes, i, { index, filename, jsx }) { nodes.splice(i, 0, buildGUmiUIFlag({ index, filename, jsx })); } function addUmiUIFlag(node, { filename, replace }) { if ((0, _util.isJSXElement)(node)) { if ((0, _util.isChildFunc)(node)) { return; } if ((0, _util.haveChildren)(node)) { if (t().isJSXElement(node) || t().isJSXFragment(node)) { let index = node.children.filter(n => (0, _util.isJSXElement)(n)).length; let i = node.children.length - 1; while (i >= 0) { const child = node.children[i]; if ((0, _util.isJSXElement)(child) || i === 0) { addFlagToIndex(node.children, i === 0 ? i : i + 1, { index, filename, jsx: true }); index -= 1; } i -= 1; } } else { const args = node.arguments; let index = args.filter(n => (0, _util.isReactCreateElement)(n)).length; let i = args.length - 1; while (i >= 1) { const arg = args[i]; if ((0, _util.isReactCreateElement)(arg) || i === 1) { addFlagToIndex(args, i + 1, { index, filename, jsx: false }); index -= 1; } i -= 1; } } } else { // root 节点没有 children,则在外面套一层 replace(t().isJSXElement(node) ? t().jsxFragment(t().jsxOpeningFragment(), t().jsxClosingFragment(), [buildGUmiUIFlag({ index: 0, filename, jsx: true }), node, buildGUmiUIFlag({ index: 1, filename, jsx: true })]) : t().callExpression(t().memberExpression(t().identifier('React'), t().identifier('createElement')), [t().memberExpression(t().identifier('React'), t().identifier('Fragment')), t().nullLiteral(), buildGUmiUIFlag({ index: 0, filename, jsx: false }), node, buildGUmiUIFlag({ index: 1, filename, jsx: false })])); } } else {// throw new Error(`Add umi ui flag failed, unsupported node type ${node.type}.`); } } function isInBlackList(node, path) { if (t().isJSXElement(node)) { const name = node.openingElement.name.name; if (path.scope.hasBinding(name)) { const p = path.scope.getBinding(name).path; const source = p.parentPath.node.source; // 只处理 import 的声明 if (!t().isImportDeclaration(p.parentPath.node)) return; if (['react-document-title', 'react-intl'].includes(source.value)) { return true; } // antd 和 @alipay/tech-ui 里除部分用于布局的组件之外,其他组件作为根组件不会插入编辑区 if ((source.value === 'antd' || source.value === '@alipay/bigfish/antd') && t().isImportSpecifier(p.node) && t().isIdentifier(p.node.imported) && !['Card', 'Grid', 'Layout'].includes(p.node.imported.name)) { return true; } if (source.value === '@alipay/tech-ui' && t().isImportSpecifier(p.node) && t().isIdentifier(p.node.imported) && !['PageContainer'].includes(p.node.imported.name)) { return true; } if (t().isImportSpecifier(p.node) && t().isIdentifier(p.node.imported) && ['Switch', 'Route', 'Router', 'StaticRouter', 'Redirect', 'Link', 'NavLink', 'HashRouter', 'BrowserRouter'].includes(p.node.imported.name)) { return true; } } } } let layoutIndexByFilename = {}; /** * 检查是否走 Babel,目前只针对 /pages/ 或 /page/ 目录下的页面 * 其它不作为添加的入口 * @param filename 路径名 */ const checkPathFilename = filename => { if (winPath(filename).indexOf('pages/') > -1 || winPath(filename).indexOf('page/') > -1) { return true; } return false; }; return { visitor: { Program: { enter(path, state) { // hmr 时会重复编译相同文件 layoutIndexByFilename = {}; const filename = state.filename, _state$opts = state.opts, opts = _state$opts === void 0 ? {} : _state$opts; (0, _assert().default)(opts.doTransform, 'opts.doTransform must supplied'); if (!opts.doTransform(filename)) return; const node = path.node; let d = (0, _util.findExportDefaultDeclaration)(node); // Support hoc while (t().isCallExpression(d)) { // eslint-disable-next-line d = d.arguments[0]; } d = (0, _util.getIdentifierDeclaration)(d, path); // Support hoc again while (t().isCallExpression(d)) { // eslint-disable-next-line d = d.arguments[0]; } const ret = (0, _util.getReturnNode)(d, path); if (ret) { const retNode = ret.node, replace = ret.replace; if (retNode && !isInBlackList(retNode, path) && checkPathFilename(filename)) { addUmiUIFlag(retNode, { filename: winPath(filename), replace }); } } } }, CallExpression(path, state) { const filename = state.filename, _state$opts2 = state.opts, opts = _state$opts2 === void 0 ? {} : _state$opts2; // 不限于路由组件,因为添加进来的区块不是路由组件 // assert(opts.doTransform, 'opts.doTransform must supplied'); // if (!opts.doTransform(filename)) return; const node = path.node; const callee = node.callee, args = node.arguments; // e.g. // _react.default.createElement("div", null, "INSERT_BLOCK_PLACEHOLDER") if (t().isStringLiteral(args[2]) && args[2].value.startsWith(_constants.INSERT_BLOCK_PLACEHOLDER) && t().isMemberExpression(callee) && t().isIdentifier(callee.property, { name: 'createElement' })) { if (!layoutIndexByFilename[filename]) { layoutIndexByFilename[filename] = 0; } const index = layoutIndexByFilename[filename]; let content = null; if (args[2].value.startsWith(`${_constants.INSERT_BLOCK_PLACEHOLDER}:`)) { content = args[2].value.replace(`${_constants.INSERT_BLOCK_PLACEHOLDER}:`, ''); } args[2] = buildGUmiUIFlag({ index: `${_constants.BLOCK_LAYOUT_PREFIX}${index}`, filename: winPath(filename), jsx: false, inline: true, content }); layoutIndexByFilename[filename] += 1; } // _react.default.createElement(_umi.UmiUIFlag, null) if (t().isMemberExpression(callee) && t().isIdentifier(callee.property, { name: 'createElement' }) && t().isIdentifier(args[0]) && args[0].name === _constants.UMI_UI_FLAG_PLACEHOLDER) { if (!layoutIndexByFilename[filename]) { layoutIndexByFilename[filename] = 0; } const index = layoutIndexByFilename[filename]; const content = null; let inline = false; if (t().isObjectExpression(args[1]) && args[1].properties.some(property => { var _property$key, _property$value; return t().isProperty(property) && ((_property$key = property.key) === null || _property$key === void 0 ? void 0 : _property$key.name) === 'inline' && ((_property$value = property.value) === null || _property$value === void 0 ? void 0 : _property$value.value) === true; })) { inline = true; } path.replaceWith(buildGUmiUIFlag({ index: `${_constants.BLOCK_LAYOUT_PREFIX}${index}`, filename: winPath(filename), jsx: false, inline, content })); layoutIndexByFilename[filename] += 1; } } } }; }; exports.default = _default;