what-compiler 0.6.0 → 0.6.1

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.
@@ -507,6 +507,27 @@ function whatBabelPlugin({ types: t }) {
507
507
  continue;
508
508
  }
509
509
  const attrName = getAttrName(attr);
510
+ if (attrName === "ref") {
511
+ const refExpr = getAttributeValue(attr.value);
512
+ statements.push(
513
+ t.expressionStatement(
514
+ t.conditionalExpression(
515
+ t.binaryExpression(
516
+ "===",
517
+ t.unaryExpression("typeof", refExpr),
518
+ t.stringLiteral("function")
519
+ ),
520
+ t.callExpression(t.cloneNode(refExpr), [t.identifier(elId)]),
521
+ t.assignmentExpression(
522
+ "=",
523
+ t.memberExpression(t.cloneNode(refExpr), t.identifier("current")),
524
+ t.identifier(elId)
525
+ )
526
+ )
527
+ )
528
+ );
529
+ continue;
530
+ }
510
531
  if (attrName.startsWith("on") && !attrName.includes("|")) {
511
532
  const event = attrName.slice(2).toLowerCase();
512
533
  const handler = getAttributeValue(attr.value);
@@ -657,6 +678,7 @@ function whatBabelPlugin({ types: t }) {
657
678
  }
658
679
  }
659
680
  function applyDynamicChildren(statements, elId, children, parentNode, state) {
681
+ const entries = [];
660
682
  let childIndex = 0;
661
683
  for (const child of children) {
662
684
  if (t.isJSXText(child)) {
@@ -666,8 +688,57 @@ function whatBabelPlugin({ types: t }) {
666
688
  }
667
689
  if (t.isJSXExpressionContainer(child)) {
668
690
  if (t.isJSXEmptyExpression(child.expression)) continue;
669
- const expr = child.expression;
670
- const marker = buildChildAccess(elId, childIndex);
691
+ entries.push({ type: "expression", child, childIndex });
692
+ childIndex++;
693
+ continue;
694
+ }
695
+ if (t.isJSXElement(child)) {
696
+ const childTag = child.openingElement.name.name;
697
+ if (isComponent(childTag) || childTag === "For" || childTag === "Show") {
698
+ entries.push({ type: "component", child, childIndex });
699
+ childIndex++;
700
+ } else {
701
+ const hasAnythingDynamic = child.openingElement.attributes.some(isDynamicAttr) || child.openingElement.attributes.some((a) => !t.isJSXSpreadAttribute(a) && getAttrName(a)?.startsWith("on")) || !child.children.every(isStaticChild);
702
+ entries.push({ type: "static", child, childIndex, hasAnythingDynamic });
703
+ childIndex++;
704
+ }
705
+ continue;
706
+ }
707
+ if (t.isJSXFragment(child)) {
708
+ entries.push({ type: "fragment", child });
709
+ }
710
+ }
711
+ const entriesNeedingRef = entries.filter(
712
+ (e) => e.type === "expression" || e.type === "component" || e.type === "static" && e.hasAnythingDynamic
713
+ );
714
+ const hasDynamicInsert = entries.some((e) => e.type === "expression" || e.type === "component");
715
+ const needsPreCapture = entriesNeedingRef.length >= 2 && hasDynamicInsert;
716
+ const markerVars = /* @__PURE__ */ new Map();
717
+ if (needsPreCapture) {
718
+ for (const entry of entriesNeedingRef) {
719
+ const varName = `_m$${entry.childIndex}`;
720
+ const markerVar = state.nextVarId();
721
+ markerVars.set(entry.childIndex, markerVar);
722
+ statements.push(
723
+ t.variableDeclaration("const", [
724
+ t.variableDeclarator(
725
+ t.identifier(markerVar),
726
+ buildChildAccess(elId, entry.childIndex)
727
+ )
728
+ ])
729
+ );
730
+ }
731
+ }
732
+ function getMarker(idx) {
733
+ if (markerVars.has(idx)) {
734
+ return t.identifier(markerVars.get(idx));
735
+ }
736
+ return buildChildAccess(elId, idx);
737
+ }
738
+ for (const entry of entries) {
739
+ if (entry.type === "expression") {
740
+ const expr = entry.child.expression;
741
+ const marker = getMarker(entry.childIndex);
671
742
  state.needsInsert = true;
672
743
  if (isPotentiallyReactive(expr, state.signalNames, state.importedIdentifiers)) {
673
744
  const insertCall = t.callExpression(t.identifier("_$insert"), [
@@ -695,46 +766,44 @@ function whatBabelPlugin({ types: t }) {
695
766
  )
696
767
  );
697
768
  }
698
- childIndex++;
699
769
  continue;
700
770
  }
701
- if (t.isJSXElement(child)) {
702
- const childTag = child.openingElement.name.name;
703
- if (isComponent(childTag) || childTag === "For" || childTag === "Show") {
704
- const transformed = transformElementFineGrained({ node: child }, state);
705
- const marker = buildChildAccess(elId, childIndex);
706
- state.needsInsert = true;
771
+ if (entry.type === "component") {
772
+ const transformed = transformElementFineGrained({ node: entry.child }, state);
773
+ const marker = getMarker(entry.childIndex);
774
+ state.needsInsert = true;
775
+ statements.push(
776
+ t.expressionStatement(
777
+ t.callExpression(t.identifier("_$insert"), [
778
+ t.identifier(elId),
779
+ transformed,
780
+ marker
781
+ ])
782
+ )
783
+ );
784
+ continue;
785
+ }
786
+ if (entry.type === "static" && entry.hasAnythingDynamic) {
787
+ let childElRef;
788
+ if (markerVars.has(entry.childIndex)) {
789
+ childElRef = markerVars.get(entry.childIndex);
790
+ } else {
791
+ childElRef = state.nextVarId();
707
792
  statements.push(
708
- t.expressionStatement(
709
- t.callExpression(t.identifier("_$insert"), [
710
- t.identifier(elId),
711
- transformed,
712
- marker
713
- ])
714
- )
793
+ t.variableDeclaration("const", [
794
+ t.variableDeclarator(
795
+ t.identifier(childElRef),
796
+ buildChildAccess(elId, entry.childIndex)
797
+ )
798
+ ])
715
799
  );
716
- childIndex++;
717
- } else {
718
- const hasAnythingDynamic = child.openingElement.attributes.some(isDynamicAttr) || child.openingElement.attributes.some((a) => !t.isJSXSpreadAttribute(a) && getAttrName(a)?.startsWith("on")) || !child.children.every(isStaticChild);
719
- if (hasAnythingDynamic) {
720
- const childElId = state.nextVarId();
721
- statements.push(
722
- t.variableDeclaration("const", [
723
- t.variableDeclarator(
724
- t.identifier(childElId),
725
- buildChildAccess(elId, childIndex)
726
- )
727
- ])
728
- );
729
- applyDynamicAttrs(statements, childElId, child.openingElement.attributes, state);
730
- applyDynamicChildren(statements, childElId, child.children, child, state);
731
- }
732
- childIndex++;
733
800
  }
801
+ applyDynamicAttrs(statements, childElRef, entry.child.openingElement.attributes, state);
802
+ applyDynamicChildren(statements, childElRef, entry.child.children, entry.child, state);
734
803
  continue;
735
804
  }
736
- if (t.isJSXFragment(child)) {
737
- for (const fChild of child.children) {
805
+ if (entry.type === "fragment") {
806
+ for (const fChild of entry.child.children) {
738
807
  if (t.isJSXExpressionContainer(fChild) && !t.isJSXEmptyExpression(fChild.expression)) {
739
808
  state.needsInsert = true;
740
809
  const expr = fChild.expression;