babel-plugin-jsx-dom-expressions 0.33.14 → 0.34.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +176 -54
  2. package/package.json +2 -2
package/index.js CHANGED
@@ -289,7 +289,11 @@ function isDynamic(path, { checkMember, checkTags, checkCallExpressions = true,
289
289
  }
290
290
  if (
291
291
  (checkCallExpressions && t__namespace.isCallExpression(expr)) ||
292
- (checkMember && (t__namespace.isMemberExpression(expr) || t__namespace.isOptionalMemberExpression(expr))) ||
292
+ (checkMember &&
293
+ (t__namespace.isMemberExpression(expr) ||
294
+ t__namespace.isOptionalMemberExpression(expr) ||
295
+ t__namespace.isSpreadElement(expr) ||
296
+ (t__namespace.isBinaryExpression(expr) && expr.operator === "in"))) ||
293
297
  (checkTags && (t__namespace.isJSXElement(expr) || t__namespace.isJSXFragment(expr)))
294
298
  )
295
299
  return true;
@@ -314,6 +318,9 @@ function isDynamic(path, { checkMember, checkTags, checkCallExpressions = true,
314
318
  SpreadElement(p) {
315
319
  checkMember && (dynamic = true) && p.stop();
316
320
  },
321
+ BinaryExpression(p) {
322
+ checkMember && p.node.operator === "in" && (dynamic = true) && p.stop();
323
+ },
317
324
  JSXElement(p) {
318
325
  checkTags ? (dynamic = true) && p.stop() : p.skip();
319
326
  },
@@ -541,7 +548,8 @@ function transformElement$3(path, info) {
541
548
  tagName,
542
549
  renderer: "dom"
543
550
  };
544
- if (tagName === "html" && config.hydratable) results.skipTemplate = true;
551
+ if (config.hydratable && (tagName === "html" || tagName === "head" || tagName === "body"))
552
+ results.skipTemplate = true;
545
553
  if (wrapSVG) results.template = "<svg>" + results.template;
546
554
  if (!info.skipId) results.id = path.scope.generateUidIdentifier("el$");
547
555
  transformAttributes$2(path, results);
@@ -884,14 +892,22 @@ function transformAttributes$2(path, results) {
884
892
  t__namespace.unaryExpression("typeof", refIdentifier),
885
893
  t__namespace.stringLiteral("function")
886
894
  ),
887
- t__namespace.callExpression(refIdentifier, [elem]),
895
+ t__namespace.callExpression(
896
+ registerImportMethod(path, "use", getRendererConfig(path, "dom").moduleName),
897
+ [refIdentifier, elem]
898
+ ),
888
899
  t__namespace.assignmentExpression("=", value.expression, elem)
889
900
  )
890
901
  )
891
902
  );
892
903
  } else if (isFunction || t__namespace.isFunction(value.expression)) {
893
904
  results.exprs.unshift(
894
- t__namespace.expressionStatement(t__namespace.callExpression(value.expression, [elem]))
905
+ t__namespace.expressionStatement(
906
+ t__namespace.callExpression(
907
+ registerImportMethod(path, "use", getRendererConfig(path, "dom").moduleName),
908
+ [value.expression, elem]
909
+ )
910
+ )
895
911
  );
896
912
  } else if (t__namespace.isCallExpression(value.expression)) {
897
913
  const refIdentifier = path.scope.generateUidIdentifier("_ref$");
@@ -907,7 +923,10 @@ function transformAttributes$2(path, results) {
907
923
  t__namespace.unaryExpression("typeof", refIdentifier),
908
924
  t__namespace.stringLiteral("function")
909
925
  ),
910
- t__namespace.callExpression(refIdentifier, [elem])
926
+ t__namespace.callExpression(
927
+ registerImportMethod(path, "use", getRendererConfig(path, "dom").moduleName),
928
+ [refIdentifier, elem]
929
+ )
911
930
  )
912
931
  )
913
932
  );
@@ -917,15 +936,19 @@ function transformAttributes$2(path, results) {
917
936
  node.name.name.type = "Identifier";
918
937
  results.exprs.unshift(
919
938
  t__namespace.expressionStatement(
920
- t__namespace.callExpression(node.name.name, [
921
- elem,
922
- t__namespace.arrowFunctionExpression(
923
- [],
924
- t__namespace.isJSXEmptyExpression(value.expression)
925
- ? t__namespace.booleanLiteral(true)
926
- : value.expression
927
- )
928
- ])
939
+ t__namespace.callExpression(
940
+ registerImportMethod(path, "use", getRendererConfig(path, "dom").moduleName),
941
+ [
942
+ node.name.name,
943
+ elem,
944
+ t__namespace.arrowFunctionExpression(
945
+ [],
946
+ t__namespace.isJSXEmptyExpression(value.expression)
947
+ ? t__namespace.booleanLiteral(true)
948
+ : value.expression
949
+ )
950
+ ]
951
+ )
929
952
  )
930
953
  );
931
954
  } else if (key === "children") {
@@ -1547,7 +1570,11 @@ function appendToTemplate(template, value) {
1547
1570
  }
1548
1571
 
1549
1572
  function transformElement$2(path, info) {
1550
- let tagName = getTagName(path.node),
1573
+ // contains spread attributes
1574
+ if (path.node.openingElement.attributes.some(a => t__namespace.isJSXSpreadAttribute(a)))
1575
+ return createElement(path, info);
1576
+
1577
+ const tagName = getTagName(path.node),
1551
1578
  config = getConfig(path),
1552
1579
  voidTag = VoidElements.indexOf(tagName) > -1,
1553
1580
  results = {
@@ -1676,12 +1703,8 @@ function transformToObject(attrName, attributes, selectedAttributes) {
1676
1703
  }
1677
1704
  }
1678
1705
 
1679
- function transformAttributes$1(path, results) {
1680
- let children;
1681
- const tagName = getTagName(path.node),
1682
- isSVG = SVGElements.has(tagName),
1683
- hasChildren = path.node.children.length > 0,
1684
- attributes = path.get("openingElement").get("attributes"),
1706
+ function normalizeAttributes(path) {
1707
+ const attributes = path.get("openingElement").get("attributes"),
1685
1708
  styleAttributes = attributes.filter(
1686
1709
  a => t__namespace.isJSXNamespacedName(a.node.name) && a.node.name.namespace.name === "style"
1687
1710
  ),
@@ -1735,28 +1758,18 @@ function transformAttributes$1(path, results) {
1735
1758
  first.value = t__namespace.JSXExpressionContainer(t__namespace.TemplateLiteral(quasis, values));
1736
1759
  }
1737
1760
  if (styleAttributes.length) transformToObject("style", attributes, styleAttributes);
1761
+ return attributes;
1762
+ }
1763
+
1764
+ function transformAttributes$1(path, results) {
1765
+ const tagName = getTagName(path.node),
1766
+ isSVG = SVGElements.has(tagName),
1767
+ hasChildren = path.node.children.length > 0,
1768
+ attributes = normalizeAttributes(path);
1769
+ let children;
1738
1770
 
1739
1771
  attributes.forEach(attribute => {
1740
1772
  const node = attribute.node;
1741
- if (t__namespace.isJSXSpreadAttribute(node)) {
1742
- appendToTemplate(results.template, " ");
1743
- results.template.push("");
1744
- results.templateValues.push(
1745
- t__namespace.callExpression(registerImportMethod(attribute, "ssrSpread"), [
1746
- isDynamic(attribute.get("argument"), {
1747
- checkMember: true,
1748
- native: true
1749
- })
1750
- ? t__namespace.isCallExpression(node.argument) && !node.argument.arguments.length
1751
- ? node.argument.callee
1752
- : t__namespace.arrowFunctionExpression([], node.argument)
1753
- : node.argument,
1754
- t__namespace.booleanLiteral(isSVG),
1755
- t__namespace.booleanLiteral(hasChildren)
1756
- ])
1757
- );
1758
- return;
1759
- }
1760
1773
 
1761
1774
  let value = node.value,
1762
1775
  key = t__namespace.isJSXNamespacedName(node.name)
@@ -1855,8 +1868,7 @@ function transformAttributes$1(path, results) {
1855
1868
  key = "class";
1856
1869
  doEscape = false;
1857
1870
  }
1858
- if (doEscape)
1859
- value.expression = escapeExpression(path, value.expression, true);
1871
+ if (doEscape) value.expression = escapeExpression(path, value.expression, true);
1860
1872
 
1861
1873
  if (!doEscape || t__namespace.isLiteral(value.expression) || t__namespace.isBinaryExpression(value.expression)) {
1862
1874
  key = toAttribute(key, isSVG);
@@ -1957,6 +1969,89 @@ function transformChildren$1(path, results, { hydratable }) {
1957
1969
  });
1958
1970
  }
1959
1971
 
1972
+ function createElement(path, { topLevel }) {
1973
+ const tagName = getTagName(path.node),
1974
+ config = getConfig(path),
1975
+ attributes = normalizeAttributes(path);
1976
+
1977
+ const filteredChildren = filterChildren(path.get("children")),
1978
+ childNodes = filteredChildren.reduce((memo, path) => {
1979
+ if (t__namespace.isJSXText(path.node)) {
1980
+ const v = htmlEntities.decode(trimWhitespace(path.node.extra.raw));
1981
+ if (v.length) memo.push(t__namespace.stringLiteral(v));
1982
+ } else {
1983
+ const child = transformNode(path);
1984
+ memo.push(getCreateTemplate(config, path, child)(path, child, true));
1985
+ }
1986
+ return memo;
1987
+ }, []);
1988
+
1989
+ let transformed;
1990
+ if (attributes.length === 1) {
1991
+ transformed = attributes[0].node.argument;
1992
+ } else {
1993
+ transformed = t__namespace.objectExpression(
1994
+ attributes.reduce((memo, attribute) => {
1995
+ const node = attribute.node;
1996
+
1997
+ if (t__namespace.isJSXSpreadAttribute(node)) {
1998
+ const expr = node.argument;
1999
+ memo.push(t__namespace.spreadElement(expr));
2000
+ return memo;
2001
+ }
2002
+ let value = node.value,
2003
+ key = t__namespace.isJSXNamespacedName(node.name)
2004
+ ? `${node.name.namespace.name}:${node.name.name.name}`
2005
+ : node.name.name,
2006
+ reservedNameSpace =
2007
+ t__namespace.isJSXNamespacedName(node.name) && reservedNameSpaces.has(node.name.namespace.name);
2008
+ if (
2009
+ ((t__namespace.isJSXNamespacedName(node.name) && reservedNameSpace) || ChildProperties.has(key)) &&
2010
+ !t__namespace.isJSXExpressionContainer(value)
2011
+ ) {
2012
+ node.value = value = t__namespace.JSXExpressionContainer(value || t__namespace.JSXEmptyExpression());
2013
+ }
2014
+
2015
+ if (
2016
+ t__namespace.isJSXExpressionContainer(value) &&
2017
+ (reservedNameSpace ||
2018
+ ChildProperties.has(key) ||
2019
+ !(t__namespace.isStringLiteral(value.expression) || t__namespace.isNumericLiteral(value.expression)))
2020
+ ) {
2021
+ if (
2022
+ key === "ref" ||
2023
+ key.startsWith("use:") ||
2024
+ key.startsWith("prop:") ||
2025
+ key.startsWith("on")
2026
+ )
2027
+ return memo;
2028
+
2029
+ memo.push(t__namespace.objectProperty(t__namespace.stringLiteral(key), value.expression));
2030
+ } else {
2031
+ if (key === "$ServerOnly") return memo;
2032
+ if (t__namespace.isJSXExpressionContainer(value)) value = value.expression;
2033
+ memo.push(t__namespace.objectProperty(t__namespace.stringLiteral(key), value ? value : t__namespace.booleanLiteral(true)));
2034
+ }
2035
+ return memo;
2036
+ }, [])
2037
+ );
2038
+ }
2039
+
2040
+ const exprs = [
2041
+ t__namespace.callExpression(registerImportMethod(path, "ssrElement"), [
2042
+ t__namespace.stringLiteral(tagName),
2043
+ transformed,
2044
+ childNodes.length
2045
+ ? childNodes.length === 1
2046
+ ? childNodes[0]
2047
+ : t__namespace.arrayExpression(childNodes)
2048
+ : t__namespace.identifier("undefined"),
2049
+ t__namespace.booleanLiteral(Boolean(topLevel && config.hydratable))
2050
+ ])
2051
+ ];
2052
+ return { exprs, template: "" };
2053
+ }
2054
+
1960
2055
  function transformElement$1(path, info) {
1961
2056
  let tagName = getTagName(path.node),
1962
2057
  results = {
@@ -2060,14 +2155,30 @@ function transformAttributes(path, results) {
2060
2155
  t__namespace.unaryExpression("typeof", refIdentifier),
2061
2156
  t__namespace.stringLiteral("function")
2062
2157
  ),
2063
- t__namespace.callExpression(refIdentifier, [elem]),
2158
+ t__namespace.callExpression(
2159
+ registerImportMethod(
2160
+ path,
2161
+ "use",
2162
+ getRendererConfig(path, "universal").moduleName
2163
+ ),
2164
+ [refIdentifier, elem]
2165
+ ),
2064
2166
  t__namespace.assignmentExpression("=", value.expression, elem)
2065
2167
  )
2066
2168
  )
2067
2169
  );
2068
2170
  } else if (t__namespace.isFunction(value.expression)) {
2069
2171
  results.exprs.unshift(
2070
- t__namespace.expressionStatement(t__namespace.callExpression(value.expression, [elem]))
2172
+ t__namespace.expressionStatement(
2173
+ t__namespace.callExpression(
2174
+ registerImportMethod(
2175
+ path,
2176
+ "use",
2177
+ getRendererConfig(path, "universal").moduleName
2178
+ ),
2179
+ [value.expression, elem]
2180
+ )
2181
+ )
2071
2182
  );
2072
2183
  } else if (t__namespace.isCallExpression(value.expression)) {
2073
2184
  const refIdentifier = path.scope.generateUidIdentifier("_ref$");
@@ -2083,7 +2194,14 @@ function transformAttributes(path, results) {
2083
2194
  t__namespace.unaryExpression("typeof", refIdentifier),
2084
2195
  t__namespace.stringLiteral("function")
2085
2196
  ),
2086
- t__namespace.callExpression(refIdentifier, [elem])
2197
+ t__namespace.callExpression(
2198
+ registerImportMethod(
2199
+ path,
2200
+ "use",
2201
+ getRendererConfig(path, "universal").moduleName
2202
+ ),
2203
+ [refIdentifier, elem]
2204
+ )
2087
2205
  )
2088
2206
  )
2089
2207
  );
@@ -2093,15 +2211,19 @@ function transformAttributes(path, results) {
2093
2211
  node.name.name.type = "Identifier";
2094
2212
  results.exprs.unshift(
2095
2213
  t__namespace.expressionStatement(
2096
- t__namespace.callExpression(node.name.name, [
2097
- elem,
2098
- t__namespace.arrowFunctionExpression(
2099
- [],
2100
- t__namespace.isJSXEmptyExpression(value.expression)
2101
- ? t__namespace.booleanLiteral(true)
2102
- : value.expression
2103
- )
2104
- ])
2214
+ t__namespace.callExpression(
2215
+ registerImportMethod(path, "use", getRendererConfig(path, "universal").moduleName),
2216
+ [
2217
+ node.name.name,
2218
+ elem,
2219
+ t__namespace.arrowFunctionExpression(
2220
+ [],
2221
+ t__namespace.isJSXEmptyExpression(value.expression)
2222
+ ? t__namespace.booleanLiteral(true)
2223
+ : value.expression
2224
+ )
2225
+ ]
2226
+ )
2105
2227
  )
2106
2228
  );
2107
2229
  } else if (key === "children") {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "babel-plugin-jsx-dom-expressions",
3
3
  "description": "A JSX to DOM plugin that wraps expressions for fine grained change detection",
4
- "version": "0.33.14",
4
+ "version": "0.34.0-beta.2",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -27,5 +27,5 @@
27
27
  "peerDependencies": {
28
28
  "@babel/core": "^7.0.0"
29
29
  },
30
- "gitHead": "22cfcec0f4a6ab639fc37997bcb8e0ff8563397d"
30
+ "gitHead": "80b54ffb1029d3fc735fd0604ead837758071fec"
31
31
  }