UNPKG

4.16 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const t = require("babel-types");
4const utils_1 = require("./utils");
5const jsx_1 = require("./jsx");
6const lodash_1 = require("lodash");
7const renderPropsMap = new Map();
8const RENDER_PROPS_EVENTS = '$$renderPropsEvents';
9function injectRenderPropsListener(attrPath, attrName, attrExpr, componentName) {
10 const randomLetters = utils_1.createRandomLetters(5);
11 const renderClosureFuncName = attrName + randomLetters;
12 const jsxDecl = utils_1.buildConstVariableDeclaration(renderClosureFuncName, attrExpr);
13 const block = jsx_1.buildBlockElement([], true);
14 const renderPropsArgs = t.memberExpression(t.thisExpression(), t.identifier(renderClosureFuncName));
15 renderPropsMap.set(componentName + '_' + attrName, renderClosureFuncName);
16 block.children = [
17 t.jSXExpressionContainer(t.callExpression(t.identifier(renderClosureFuncName), [renderPropsArgs]))
18 ];
19 const listener = buildListener(renderClosureFuncName, renderPropsArgs);
20 const stemParent = attrPath.getStatementParent();
21 stemParent.insertBefore(listener);
22 stemParent.insertBefore(jsxDecl);
23 attrPath.get('value').replaceWith(t.jSXExpressionContainer(block));
24 setRenderPropsEvents(attrPath, renderClosureFuncName);
25}
26exports.injectRenderPropsListener = injectRenderPropsListener;
27function setRenderPropsEvents(attrPath, renderClosureFuncName) {
28 const classDecl = attrPath.findParent(p => p.isClassDeclaration());
29 if (classDecl && classDecl.isClassDeclaration()) {
30 let hasEvent = false;
31 for (const s of classDecl.node.body.body) {
32 if (t.isClassProperty(s) && s.key.name === RENDER_PROPS_EVENTS && t.isArrayExpression(s.value)) {
33 hasEvent = true;
34 if (s.value.elements.some(e => t.isStringLiteral(e) && e.value === renderClosureFuncName)) {
35 break;
36 }
37 s.value.elements.push(t.stringLiteral(renderClosureFuncName));
38 }
39 }
40 if (!hasEvent) {
41 classDecl.node.body.body.push(t.classProperty(t.identifier(RENDER_PROPS_EVENTS), t.arrayExpression([t.stringLiteral(renderClosureFuncName)])));
42 }
43 }
44}
45function injectRenderPropsEmiter(callExpr, attrName) {
46 const classDecl = callExpr.findParent(p => p.isClassDeclaration());
47 const classDeclName = classDecl && classDecl.isClassDeclaration() && lodash_1.get(classDecl, 'node.id.name', '');
48 if (typeof classDeclName !== 'string') {
49 throw utils_1.codeFrameError(classDecl, '使用 render props 必须指定 class 的名称。');
50 }
51 const renderClosureFuncName = renderPropsMap.get(classDeclName + '_' + attrName) || '';
52 const args = [t.stringLiteral(renderClosureFuncName)];
53 if (Array.isArray(callExpr.node.arguments) && callExpr.node.arguments.length) {
54 args.push(callExpr.node.arguments[0]);
55 }
56 const emitter = t.callExpression(t.memberExpression(buildEventCenterMemberExpr(), t.identifier('trigger')), args);
57 const stemParent = callExpr.getStatementParent();
58 stemParent.insertBefore(t.expressionStatement(emitter));
59}
60exports.injectRenderPropsEmiter = injectRenderPropsEmiter;
61function buildListener(renderClosureFuncName, renderPropsArgs) {
62 return t.expressionStatement(t.callExpression(t.memberExpression(buildEventCenterMemberExpr(), t.identifier('on')), [t.stringLiteral(renderClosureFuncName), t.arrowFunctionExpression([t.identifier('e')], t.blockStatement([
63 t.ifStatement(t.unaryExpression('!', t.callExpression(t.memberExpression(t.identifier('Taro'), t.identifier('shallowEqual')), [t.identifier('e'), renderPropsArgs])), t.blockStatement([
64 t.expressionStatement(t.assignmentExpression('=', renderPropsArgs, t.identifier('e'))),
65 t.expressionStatement(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('setState')), [t.objectExpression([])]))
66 ]))
67 ]))]));
68}
69function buildEventCenterMemberExpr() {
70 return t.memberExpression(t.identifier('Taro'), t.identifier('eventCenter'));
71}
72//# sourceMappingURL=render-props.js.map
\No newline at end of file