babel-plugin-jsx-dom-expressions 0.29.13 → 0.29.17

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 +113 -86
  2. package/package.json +2 -2
package/index.js CHANGED
@@ -46,7 +46,6 @@ var config = {
46
46
 
47
47
  const booleans = [
48
48
  "allowfullscreen",
49
- "allowpaymentrequest",
50
49
  "async",
51
50
  "autofocus",
52
51
  "autoplay",
@@ -56,8 +55,8 @@ const booleans = [
56
55
  "disabled",
57
56
  "formnovalidate",
58
57
  "hidden",
58
+ "indeterminate",
59
59
  "ismap",
60
- "itemscope",
61
60
  "loop",
62
61
  "multiple",
63
62
  "muted",
@@ -69,13 +68,12 @@ const booleans = [
69
68
  "required",
70
69
  "reversed",
71
70
  "seamless",
72
- "selected",
73
- "truespeed"
71
+ "selected"
74
72
  ];
75
73
 
76
74
  const BooleanAttributes = new Set(booleans);
77
75
 
78
- const Properties = new Set(["className", "indeterminate", "value", "readOnly", ...booleans]);
76
+ const Properties = new Set(["className", "value", "readOnly", "formNoValidate", "isMap", "noModule", "playsInline", ...booleans]);
79
77
 
80
78
  const ChildProperties = new Set(["innerHTML", "textContent", "innerText", "children"]);
81
79
 
@@ -87,6 +85,10 @@ const Aliases = {
87
85
 
88
86
  const PropAliases = {
89
87
  class: "className",
88
+ formnovalidate: "formNoValidate",
89
+ ismap: "isMap",
90
+ nomodule: "noModule",
91
+ playsinline: "playsInline",
90
92
  readonly: "readOnly"
91
93
  };
92
94
 
@@ -337,12 +339,11 @@ function getStaticExpression(path) {
337
339
  }
338
340
 
339
341
  // remove unnecessary JSX Text nodes
340
- function filterChildren(children, loose) {
342
+ function filterChildren(children) {
341
343
  return children.filter(
342
344
  ({ node: child }) =>
343
345
  !(t__namespace.isJSXExpressionContainer(child) && t__namespace.isJSXEmptyExpression(child.expression)) &&
344
- (!t__namespace.isJSXText(child) ||
345
- (loose ? !/^[\r\n]\s*$/.test(child.extra.raw) : !/^\s*$/.test(child.extra.raw)))
346
+ (!t__namespace.isJSXText(child) || !/^[\r\n]\s*$/.test(child.extra.raw))
346
347
  );
347
348
  }
348
349
 
@@ -588,7 +589,11 @@ function setAttr$1(path, elem, name, value, { isSVG, dynamic, prevId, isCE }) {
588
589
  const alias = PropAliases[name];
589
590
  if (namespace !== "attr" && (isChildProp || (!isSVG && isProp) || isCE || namespace === "prop")) {
590
591
  if (isCE && !isChildProp && !isProp && namespace !== "prop") name = toPropertyName(name);
591
- return t__namespace.assignmentExpression("=", t__namespace.memberExpression(elem, t__namespace.identifier(alias || name)), value);
592
+ return t__namespace.assignmentExpression(
593
+ "=",
594
+ t__namespace.memberExpression(elem, t__namespace.identifier(alias || name)),
595
+ value
596
+ );
592
597
  }
593
598
 
594
599
  let isNameSpaced = name.indexOf(":") > -1;
@@ -632,44 +637,9 @@ function transformAttributes$1(path, results) {
632
637
  tagName = getTagName(path.node),
633
638
  isSVG = SVGElements.has(tagName),
634
639
  isCE = tagName.includes("-"),
635
- hasChildren = path.node.children.length > 0,
636
- classAttributes = attributes.filter(
637
- a => a.node.name && (a.node.name.name === "class" || a.node.name.name === "className")
638
- );
639
- // combine class propertoes
640
- if (classAttributes.length > 1) {
641
- const first = classAttributes[0].node,
642
- values = [],
643
- quasis = [t__namespace.TemplateElement({ raw: "" })];
644
- for (let i = 0; i < classAttributes.length; i++) {
645
- const attr = classAttributes[i].node,
646
- isLast = i === classAttributes.length - 1;
647
- if (!t__namespace.isJSXExpressionContainer(attr.value)) {
648
- const prev = quasis.pop();
649
- quasis.push(
650
- t__namespace.TemplateElement({
651
- raw:
652
- (prev ? prev.value.raw : "") +
653
- (i ? " " : "") +
654
- `${attr.value.value}` +
655
- (isLast ? "" : " ")
656
- })
657
- );
658
- } else {
659
- values.push(t__namespace.logicalExpression("||", attr.value.expression, t__namespace.stringLiteral("")));
660
- quasis.push(t__namespace.TemplateElement({ raw: isLast ? "" : " " }));
661
- }
662
- i && attributes.splice(classAttributes[i].key, 1);
663
- }
664
- first.value = t__namespace.JSXExpressionContainer(t__namespace.TemplateLiteral(quasis, values));
665
- }
666
- path.get("openingElement").set(
667
- "attributes",
668
- attributes.map(a => a.node)
669
- );
640
+ hasChildren = path.node.children.length > 0;
670
641
 
671
642
  // preprocess styles
672
- attributes = path.get("openingElement").get("attributes");
673
643
  const styleAttribute = attributes.find(
674
644
  a =>
675
645
  a.node.name &&
@@ -721,28 +691,77 @@ function transformAttributes$1(path, results) {
721
691
  );
722
692
  if (classListAttribute) {
723
693
  let i = 0,
724
- leading = classListAttribute.node.value.expression.leadingComments;
725
- classListAttribute.node.value.expression.properties.slice().forEach((p, index) => {
694
+ leading = classListAttribute.node.value.expression.leadingComments,
695
+ classListProperties = classListAttribute.get("value").get("expression").get("properties");
696
+ classListProperties.slice().forEach((propPath, index) => {
697
+ const p = propPath.node;
698
+ const { confident, value: computed } = propPath.get("value").evaluate();
726
699
  if (leading) p.value.leadingComments = leading;
727
- path
728
- .get("openingElement")
729
- .node.attributes.splice(
730
- classListAttribute.key + ++i,
731
- 0,
732
- t__namespace.JSXAttribute(
733
- t__namespace.JSXNamespacedName(
700
+ if (!confident) {
701
+ path
702
+ .get("openingElement")
703
+ .node.attributes.splice(
704
+ classListAttribute.key + ++i,
705
+ 0,
706
+ t__namespace.JSXAttribute(
707
+ t__namespace.JSXNamespacedName(
708
+ t__namespace.JSXIdentifier("class"),
709
+ t__namespace.JSXIdentifier(t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value)
710
+ ),
711
+ t__namespace.JSXExpressionContainer(p.value)
712
+ )
713
+ );
714
+ } else if (computed) {
715
+ path
716
+ .get("openingElement")
717
+ .node.attributes.splice(
718
+ classListAttribute.key + ++i,
719
+ 0,
720
+ t__namespace.JSXAttribute(
734
721
  t__namespace.JSXIdentifier("class"),
735
- t__namespace.JSXIdentifier(t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value)
736
- ),
737
- t__namespace.JSXExpressionContainer(p.value)
738
- )
739
- );
740
- classListAttribute.node.value.expression.properties.splice(index - i - 1, 1);
722
+ t__namespace.stringLiteral(t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value)
723
+ )
724
+ );
725
+ }
726
+ classListProperties.splice(index - i - 1, 1);
741
727
  });
742
- if (!classListAttribute.node.value.expression.properties.length)
728
+ if (!classListProperties.length)
743
729
  path.get("openingElement").node.attributes.splice(classListAttribute.key, 1);
744
730
  }
745
731
 
732
+ // combine class properties
733
+ attributes = path.get("openingElement").get("attributes");
734
+ const classAttributes = attributes.filter(
735
+ a => a.node.name && (a.node.name.name === "class" || a.node.name.name === "className")
736
+ );
737
+ if (classAttributes.length > 1) {
738
+ const first = classAttributes[0].node,
739
+ values = [],
740
+ quasis = [t__namespace.TemplateElement({ raw: "" })];
741
+ for (let i = 0; i < classAttributes.length; i++) {
742
+ const attr = classAttributes[i].node,
743
+ isLast = i === classAttributes.length - 1;
744
+ if (!t__namespace.isJSXExpressionContainer(attr.value)) {
745
+ const prev = quasis.pop();
746
+ quasis.push(
747
+ t__namespace.TemplateElement({
748
+ raw: (prev ? prev.value.raw : "") + `${attr.value.value}` + (isLast ? "" : " ")
749
+ })
750
+ );
751
+ } else {
752
+ values.push(t__namespace.logicalExpression("||", attr.value.expression, t__namespace.stringLiteral("")));
753
+ quasis.push(t__namespace.TemplateElement({ raw: isLast ? "" : " " }));
754
+ }
755
+ i && attributes.splice(classAttributes[i].key, 1);
756
+ }
757
+ if (values.length) first.value = t__namespace.JSXExpressionContainer(t__namespace.TemplateLiteral(quasis, values));
758
+ else first.value = t__namespace.stringLiteral(quasis[0].value.raw);
759
+ }
760
+ path.get("openingElement").set(
761
+ "attributes",
762
+ attributes.map(a => a.node)
763
+ );
764
+
746
765
  path
747
766
  .get("openingElement")
748
767
  .get("attributes")
@@ -788,6 +807,10 @@ function transformAttributes$1(path, results) {
788
807
  !(t__namespace.isStringLiteral(value.expression) || t__namespace.isNumericLiteral(value.expression)))
789
808
  ) {
790
809
  if (key === "ref") {
810
+ // Normalize expressions for non-null and type-as
811
+ while (t__namespace.isTSNonNullExpression(value.expression) || t__namespace.isTSAsExpression(value.expression)) {
812
+ value.expression = value.expression.expression;
813
+ }
791
814
  if (t__namespace.isLVal(value.expression)) {
792
815
  const refIdentifier = path.scope.generateUidIdentifier("_ref$");
793
816
  results.exprs.unshift(
@@ -966,15 +989,9 @@ function transformAttributes$1(path, results) {
966
989
  if (key === "textContent") {
967
990
  nextElem = attribute.scope.generateUidIdentifier("el$");
968
991
  children = t__namespace.JSXText(" ");
969
- children.extra = { raw: " ", rawValue: " "};
992
+ children.extra = { raw: " ", rawValue: " " };
970
993
  results.decl.push(
971
- t__namespace.variableDeclarator(
972
- nextElem,
973
- t__namespace.memberExpression(
974
- elem,
975
- t__namespace.identifier("firstChild")
976
- )
977
- )
994
+ t__namespace.variableDeclarator(nextElem, t__namespace.memberExpression(elem, t__namespace.identifier("firstChild")))
978
995
  );
979
996
  }
980
997
  results.dynamics.push({ elem: nextElem, key, value: value.expression, isSVG, isCE });
@@ -997,7 +1014,7 @@ function transformAttributes$1(path, results) {
997
1014
  } else {
998
1015
  !isSVG && (key = key.toLowerCase());
999
1016
  results.template += ` ${key}`;
1000
- results.template += value ? `="${value.value}"` : `=""`;
1017
+ results.template += value ? `="${value.value}"` : "";
1001
1018
  }
1002
1019
  }
1003
1020
  });
@@ -1037,7 +1054,7 @@ function transformChildren$1(path, results) {
1037
1054
  tagName = getTagName(path.node),
1038
1055
  nextPlaceholder,
1039
1056
  i = 0;
1040
- const filteredChildren = filterChildren(path.get("children"), true),
1057
+ const filteredChildren = filterChildren(path.get("children")),
1041
1058
  childNodes = filteredChildren
1042
1059
  .map(
1043
1060
  (child, index) =>
@@ -1221,7 +1238,7 @@ function detectExpressions(children, index) {
1221
1238
  )
1222
1239
  )
1223
1240
  return true;
1224
- const nextChildren = filterChildren(children[i].get("children"), true);
1241
+ const nextChildren = filterChildren(children[i].get("children"));
1225
1242
  if (nextChildren.length) if (detectExpressions(nextChildren, 0)) return true;
1226
1243
  }
1227
1244
  }
@@ -1451,7 +1468,6 @@ function setAttr(results, name, value, isSVG) {
1451
1468
  let parts;
1452
1469
  if ((parts = name.split(":")) && parts[1] && reservedNameSpaces.has(parts[0])) {
1453
1470
  name = parts[1];
1454
- parts[0];
1455
1471
  }
1456
1472
 
1457
1473
  name = toAttribute(name, isSVG);
@@ -1727,7 +1743,7 @@ function transformAttributes(path, results) {
1727
1743
  if (t__namespace.isJSXExpressionContainer(value)) value = value.expression;
1728
1744
  key = toAttribute(key, isSVG);
1729
1745
  appendToTemplate(results.template, ` ${key}`);
1730
- appendToTemplate(results.template, value ? `="${escapeHTML(value.value, true)}"` : `=""`);
1746
+ appendToTemplate(results.template, value ? `="${escapeHTML(value.value, true)}"` : "");
1731
1747
  }
1732
1748
  });
1733
1749
  if (!hasChildren && children) {
@@ -1769,7 +1785,7 @@ function transformClasslistObject(path, expr, values, quasis) {
1769
1785
  function transformChildren(path, results) {
1770
1786
  const { hydratable } = config,
1771
1787
  doNotEscape = path.doNotEscape;
1772
- const filteredChildren = filterChildren(path.get("children"), true);
1788
+ const filteredChildren = filterChildren(path.get("children"));
1773
1789
  filteredChildren.forEach(node => {
1774
1790
  const child = transformNode(node, { doNotEscape });
1775
1791
  appendToTemplate(results.template, child.template);
@@ -1871,6 +1887,10 @@ function transformComponent(path) {
1871
1887
  if (t__namespace.isJSXExpressionContainer(value))
1872
1888
  if (key === "ref") {
1873
1889
  if (config.generate === "ssr") return;
1890
+ // Normalize expressions for non-null and type-as
1891
+ while (t__namespace.isTSNonNullExpression(value.expression) || t__namespace.isTSAsExpression(value.expression)) {
1892
+ value.expression = value.expression.expression;
1893
+ }
1874
1894
  if (t__namespace.isLVal(value.expression)) {
1875
1895
  const refIdentifier = path.scope.generateUidIdentifier("_ref$");
1876
1896
  runningObject.push(
@@ -1972,9 +1992,9 @@ function transformComponent(path) {
1972
1992
  );
1973
1993
  } else runningObject.push(t__namespace.objectProperty(t__namespace.identifier("children"), childResult[0]));
1974
1994
  }
1975
- props.push(t__namespace.objectExpression(runningObject));
1995
+ if (runningObject.length || !props.length) props.push(t__namespace.objectExpression(runningObject));
1976
1996
 
1977
- if (props.length > 1 && runningObject.length) {
1997
+ if (props.length > 1) {
1978
1998
  registerImportMethod(path, "mergeProps");
1979
1999
  props = [t__namespace.callExpression(t__namespace.identifier("_$mergeProps"), props)];
1980
2000
  }
@@ -2001,18 +2021,20 @@ function transformComponentChildren(children) {
2001
2021
  if (!filteredChildren.length) return;
2002
2022
  let dynamic = false;
2003
2023
 
2004
- let transformedChildren = filteredChildren.map(path => {
2024
+ let transformedChildren = filteredChildren.reduce((memo, path) => {
2005
2025
  if (t__namespace.isJSXText(path.node)) {
2006
- return t__namespace.stringLiteral(trimWhitespace(path.node.extra.rawValue));
2026
+ const v = trimWhitespace(path.node.extra.rawValue);
2027
+ if (v.length) memo.push(t__namespace.stringLiteral(v));
2007
2028
  } else {
2008
2029
  const child = transformNode(path, {
2009
2030
  topLevel: true,
2010
2031
  componentChild: true
2011
2032
  });
2012
2033
  dynamic = dynamic || child.dynamic;
2013
- return createTemplate$2(path, child, filteredChildren.length > 1);
2034
+ memo.push(createTemplate$2(path, child, filteredChildren.length > 1));
2014
2035
  }
2015
- });
2036
+ return memo;
2037
+ }, []);
2016
2038
 
2017
2039
  if (filteredChildren.length === 1) {
2018
2040
  transformedChildren = transformedChildren[0];
@@ -2040,11 +2062,16 @@ function transformFragmentChildren(children, results) {
2040
2062
  const createTemplate$2 = config.generate === "ssr" ? createTemplate : createTemplate$1,
2041
2063
  filteredChildren = filterChildren(children),
2042
2064
  singleChild = filteredChildren.length === 1,
2043
- childNodes = filteredChildren.map(path => {
2044
- if (t__namespace.isJSXText(path.node)) return t__namespace.stringLiteral(trimWhitespace(path.node.extra.raw));
2045
- const child = transformNode(path, { topLevel: true, fragmentChild: true });
2046
- return createTemplate$2(path, child, !singleChild);
2047
- });
2065
+ childNodes = filteredChildren.reduce((memo, path) => {
2066
+ if (t__namespace.isJSXText(path.node)) {
2067
+ const v = trimWhitespace(path.node.extra.raw);
2068
+ if (v.length) memo.push(t__namespace.stringLiteral(v));
2069
+ } else {
2070
+ const child = transformNode(path, { topLevel: true, fragmentChild: true });
2071
+ memo.push(createTemplate$2(path, child, !singleChild));
2072
+ }
2073
+ return memo;
2074
+ }, []);
2048
2075
  results.exprs.push(singleChild ? childNodes[0] : t__namespace.arrayExpression(childNodes));
2049
2076
  }
2050
2077
 
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.29.13",
4
+ "version": "0.29.17",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -22,5 +22,5 @@
22
22
  "@babel/plugin-syntax-jsx": "^7.10.4",
23
23
  "@babel/types": "^7.11.5"
24
24
  },
25
- "gitHead": "301546a2f0a6702d0ac00fb600c7285171657061"
25
+ "gitHead": "bdec422181ff938226a7a21b92ad4862b799f687"
26
26
  }