source: trip-planner-front/node_modules/@babel/preset-modules/src/plugins/transform-jsx-spread/index.js

Last change on this file was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 3.3 KB
Line 
1import esutils from "esutils";
2
3/**
4 * Converts JSX Spread arguments into Object Spread, avoiding Babel's helper or Object.assign injection.
5 * Input:
6 * <div a="1" {...b} />
7 * Output:
8 * <div {...{ a: "1", ...b }} />
9 * ...which Babel converts to:
10 * h("div", { a: "1", ...b })
11 */
12export default ({ types: t }) => {
13 // converts a set of JSXAttributes to an Object.assign() call
14 function convertAttributesAssign(attributes) {
15 const args = [];
16 for (let i = 0, current; i < attributes.length; i++) {
17 const node = attributes[i];
18 if (t.isJSXSpreadAttribute(node)) {
19 // the first attribute is a spread, avoid copying all other attributes onto it
20 if (i === 0) {
21 args.push(t.objectExpression([]));
22 }
23 current = null;
24 args.push(node.argument);
25 } else {
26 const name = getAttributeName(node);
27 const value = getAttributeValue(node);
28 if (!current) {
29 current = t.objectExpression([]);
30 args.push(current);
31 }
32 current.properties.push(t.objectProperty(name, value));
33 }
34 }
35 return t.callExpression(
36 t.memberExpression(t.identifier("Object"), t.identifier("assign")),
37 args
38 );
39 }
40
41 // Converts a JSXAttribute to the equivalent ObjectExpression property
42 function convertAttributeSpread(node) {
43 if (t.isJSXSpreadAttribute(node)) {
44 return t.spreadElement(node.argument);
45 }
46
47 const name = getAttributeName(node);
48 const value = getAttributeValue(node);
49 return t.inherits(t.objectProperty(name, value), node);
50 }
51
52 // Convert a JSX attribute name to an Object expression property name
53 function getAttributeName(node) {
54 if (t.isJSXNamespacedName(node.name)) {
55 return t.stringLiteral(
56 node.name.namespace.name + ":" + node.name.name.name
57 );
58 }
59 if (esutils.keyword.isIdentifierNameES6(node.name.name)) {
60 return t.identifier(node.name.name);
61 }
62 return t.stringLiteral(node.name.name);
63 }
64
65 // Convert a JSX attribute value to a JavaScript expression value
66 function getAttributeValue(node) {
67 let value = node.value || t.booleanLiteral(true);
68
69 if (t.isJSXExpressionContainer(value)) {
70 value = value.expression;
71 } else if (t.isStringLiteral(value)) {
72 value.value = value.value.replace(/\n\s+/g, " ");
73
74 // "raw" JSXText should not be used from a StringLiteral because it needs to be escaped.
75 if (value.extra && value.extra.raw) {
76 delete value.extra.raw;
77 }
78 }
79
80 return value;
81 }
82
83 return {
84 name: "transform-jsx-spread",
85 visitor: {
86 JSXOpeningElement(path, state) {
87 const useSpread = state.opts.useSpread === true;
88 const hasSpread = path.node.attributes.some(attr =>
89 t.isJSXSpreadAttribute(attr)
90 );
91
92 // ignore JSX Elements without spread or with lone spread:
93 if (!hasSpread || path.node.attributes.length === 1) return;
94
95 if (useSpread) {
96 path.node.attributes = [
97 t.jsxSpreadAttribute(
98 t.objectExpression(
99 path.node.attributes.map(convertAttributeSpread)
100 )
101 ),
102 ];
103 } else {
104 path.node.attributes = [
105 t.jsxSpreadAttribute(convertAttributesAssign(path.node.attributes)),
106 ];
107 }
108 },
109 },
110 };
111};
Note: See TracBrowser for help on using the repository browser.