babel-plugin-jsx-dom-expressions 0.32.11 → 0.32.16

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 +928 -839
  2. package/package.json +4 -4
package/index.js CHANGED
@@ -223,18 +223,29 @@ function getConfig(path) {
223
223
  return path.hub.file.metadata.config;
224
224
  }
225
225
 
226
- function registerImportMethod(path, name) {
226
+ const getRendererConfig = (path, renderer) => {
227
+ const config = getConfig(path);
228
+ return config?.renderers?.find(r => r.name === renderer) ?? config;
229
+ };
230
+
231
+ function registerImportMethod(path, name, moduleName) {
227
232
  const imports =
228
233
  path.scope.getProgramParent().data.imports ||
229
- (path.scope.getProgramParent().data.imports = new Set());
230
- const identifier = t__namespace.identifier(`_$${name}`);
231
- if (!imports.has(name)) {
232
- helperModuleImports.addNamed(path, name, getConfig(path).moduleName, {
234
+ (path.scope.getProgramParent().data.imports = new Map());
235
+ moduleName = moduleName || getConfig(path).moduleName;
236
+ if (!imports.has(`${moduleName}:${name}`)) {
237
+ let id = helperModuleImports.addNamed(path, name, moduleName, {
233
238
  nameHint: `_$${name}`
234
239
  });
235
- imports.add(name);
240
+ imports.set(`${moduleName}:${name}`, id);
241
+ return id;
242
+ } else {
243
+ let iden = imports.get(`${moduleName}:${name}`);
244
+ // the cloning is required to play well with babel-preset-env which is
245
+ // transpiling import as we add them and using the same identifier causes
246
+ // problems with the multiple identifiers of the same thing
247
+ return t__namespace.cloneDeep(iden);
236
248
  }
237
- return identifier;
238
249
  }
239
250
 
240
251
  function jsxElementNameToString(node) {
@@ -404,10 +415,7 @@ function transformCondition(path, inline, deep) {
404
415
  if (!t__namespace.isBinaryExpression(cond))
405
416
  cond = t__namespace.unaryExpression("!", t__namespace.unaryExpression("!", cond, true), true);
406
417
  id = inline
407
- ? t__namespace.callExpression(memo, [
408
- t__namespace.arrowFunctionExpression([], cond),
409
- t__namespace.booleanLiteral(true)
410
- ])
418
+ ? t__namespace.callExpression(memo, [t__namespace.arrowFunctionExpression([], cond), t__namespace.booleanLiteral(true)])
411
419
  : path.scope.generateUidIdentifier("_c$");
412
420
  expr.test = t__namespace.callExpression(id, []);
413
421
  if (t__namespace.isConditionalExpression(expr.consequent) || t__namespace.isLogicalExpression(expr.consequent)) {
@@ -433,10 +441,7 @@ function transformCondition(path, inline, deep) {
433
441
  if (!t__namespace.isBinaryExpression(cond))
434
442
  cond = t__namespace.unaryExpression("!", t__namespace.unaryExpression("!", cond, true), true);
435
443
  id = inline
436
- ? t__namespace.callExpression(memo, [
437
- t__namespace.arrowFunctionExpression([], cond),
438
- t__namespace.booleanLiteral(true)
439
- ])
444
+ ? t__namespace.callExpression(memo, [t__namespace.arrowFunctionExpression([], cond), t__namespace.booleanLiteral(true)])
440
445
  : path.scope.generateUidIdentifier("_c$");
441
446
  nextPath.node.left = t__namespace.callExpression(id, []);
442
447
  }
@@ -447,10 +452,7 @@ function transformCondition(path, inline, deep) {
447
452
  t__namespace.variableDeclarator(
448
453
  id,
449
454
  config.memoWrapper
450
- ? t__namespace.callExpression(memo, [
451
- t__namespace.arrowFunctionExpression([], cond),
452
- t__namespace.booleanLiteral(true)
453
- ])
455
+ ? t__namespace.callExpression(memo, [t__namespace.arrowFunctionExpression([], cond), t__namespace.booleanLiteral(true)])
454
456
  : t__namespace.arrowFunctionExpression([], cond)
455
457
  )
456
458
  ]),
@@ -518,744 +520,774 @@ function escapeHTML(s, attr) {
518
520
  return left < s.length ? out + s.substring(left) : out;
519
521
  }
520
522
 
521
- function transformElement$2(path, info) {
522
- let tagName = getTagName(path.node),
523
- config = getConfig(path),
524
- wrapSVG = info.topLevel && tagName != "svg" && SVGElements.has(tagName),
525
- voidTag = VoidElements.indexOf(tagName) > -1,
526
- results = {
527
- template: `<${tagName}`,
528
- decl: [],
529
- exprs: [],
530
- dynamics: [],
531
- postExprs: [],
532
- isSVG: wrapSVG,
533
- tagName
534
- };
535
- if (tagName === "html" && config.hydratable) results.skipTemplate = true;
536
- if (wrapSVG) results.template = "<svg>" + results.template;
537
- if (!info.skipId) results.id = path.scope.generateUidIdentifier("el$");
538
- transformAttributes$2(path, results);
539
- if (config.contextToCustomElements && (tagName === "slot" || tagName.indexOf("-") > -1)) {
540
- contextToCustomElement(path, results);
541
- }
542
- results.template += ">";
543
- if (!voidTag) {
544
- transformChildren$2(path, results, config);
545
- results.template += `</${tagName}>`;
546
- }
547
- if (info.topLevel && config.hydratable && results.hasHydratableEvent) {
548
- results.postExprs.push(
549
- t__namespace.expressionStatement(t__namespace.callExpression(registerImportMethod(path, "runHydrationEvents"), []))
550
- );
551
- }
552
- if (wrapSVG) results.template += "</svg>";
553
- return results;
554
- }
555
-
556
- function setAttr$2(path, elem, name, value, { isSVG, dynamic, prevId, isCE }) {
557
- // pull out namespace
558
- const config = getConfig(path);
559
- let parts, namespace;
560
- if ((parts = name.split(":")) && parts[1] && reservedNameSpaces.has(parts[0])) {
561
- name = parts[1];
562
- namespace = parts[0];
563
- }
564
-
565
- if (namespace === "style") {
566
- return t__namespace.callExpression(
567
- t__namespace.memberExpression(
568
- t__namespace.memberExpression(elem, t__namespace.identifier("style")),
569
- t__namespace.identifier("setProperty")
570
- ),
571
- [t__namespace.stringLiteral(name), value]
572
- );
573
- }
574
-
575
- if (namespace === "class") {
576
- return t__namespace.callExpression(
577
- t__namespace.memberExpression(
578
- t__namespace.memberExpression(elem, t__namespace.identifier("classList")),
579
- t__namespace.identifier("toggle")
580
- ),
581
- [t__namespace.stringLiteral(name), value]
582
- );
583
- }
584
-
585
- if (name === "style") {
586
- return t__namespace.callExpression(
587
- registerImportMethod(path, "style"),
588
- prevId ? [elem, value, prevId] : [elem, value]
589
- );
590
- }
591
-
592
- if (!isSVG && name === "class") {
593
- return t__namespace.assignmentExpression("=", t__namespace.memberExpression(elem, t__namespace.identifier("className")), value);
594
- }
595
-
596
- if (name === "classList") {
597
- return t__namespace.callExpression(
598
- registerImportMethod(path, "classList"),
599
- prevId ? [elem, value, prevId] : [elem, value]
600
- );
601
- }
602
-
603
- if (config.hydratable && name === "innerHTML") {
604
- return t__namespace.callExpression(
605
- registerImportMethod(path, "innerHTML"),
606
- [elem, value]
607
- );
608
- }
609
-
610
- if (dynamic && name === "textContent") {
611
- return t__namespace.assignmentExpression("=", t__namespace.memberExpression(elem, t__namespace.identifier("data")), value);
612
- }
613
-
614
- const isChildProp = ChildProperties.has(name);
615
- const isProp = Properties.has(name);
616
- const alias = PropAliases[name];
617
- if (namespace !== "attr" && (isChildProp || (!isSVG && isProp) || isCE || namespace === "prop")) {
618
- if (isCE && !isChildProp && !isProp && namespace !== "prop") name = toPropertyName(name);
619
- return t__namespace.assignmentExpression(
620
- "=",
621
- t__namespace.memberExpression(elem, t__namespace.identifier(alias || name)),
622
- value
623
- );
624
- }
625
-
626
- let isNameSpaced = name.indexOf(":") > -1;
627
- name = Aliases[name] || name;
628
- !isSVG && (name = name.toLowerCase());
629
- const ns = isNameSpaced && SVGNamespace[name.split(":")[0]];
630
- if (ns) {
631
- return t__namespace.callExpression(registerImportMethod(path, "setAttributeNS"), [
632
- elem,
633
- t__namespace.stringLiteral(ns),
634
- t__namespace.stringLiteral(name),
635
- value
636
- ]);
637
- } else {
638
- return t__namespace.callExpression(registerImportMethod(path, "setAttribute"), [elem, t__namespace.stringLiteral(name), value]);
639
- }
640
- }
641
-
642
- function detectResolvableEventHandler(attribute, handler) {
643
- while (t__namespace.isIdentifier(handler)) {
644
- const lookup = attribute.scope.getBinding(handler.name);
645
- if (lookup) {
646
- if (t__namespace.isVariableDeclarator(lookup.path.node)) {
647
- handler = lookup.path.node.init;
648
- } else if (t__namespace.isFunctionDeclaration(lookup.path.node)) {
649
- return true;
650
- } else return false;
651
- } else return false;
652
- }
653
- return t__namespace.isFunction(handler);
654
- }
655
-
656
- function transformAttributes$2(path, results) {
657
- let elem = results.id,
658
- hasHydratableEvent = false,
659
- children,
660
- attributes = path.get("openingElement").get("attributes");
661
- const tagName = getTagName(path.node),
662
- isSVG = SVGElements.has(tagName),
663
- isCE = tagName.includes("-"),
664
- hasChildren = path.node.children.length > 0,
665
- config = getConfig(path);
666
-
667
- // preprocess styles
668
- const styleAttribute = attributes.find(
669
- a =>
670
- a.node.name &&
671
- a.node.name.name === "style" &&
672
- t__namespace.isJSXExpressionContainer(a.node.value) &&
673
- t__namespace.isObjectExpression(a.node.value.expression) &&
674
- !a.node.value.expression.properties.some(p => t__namespace.isSpreadElement(p))
675
- );
676
- if (styleAttribute) {
677
- let i = 0,
678
- leading = styleAttribute.node.value.expression.leadingComments;
679
- styleAttribute.node.value.expression.properties.slice().forEach((p, index) => {
680
- if (!p.computed) {
681
- if (leading) p.value.leadingComments = leading;
682
- path
683
- .get("openingElement")
684
- .node.attributes.splice(
685
- styleAttribute.key + ++i,
686
- 0,
687
- t__namespace.JSXAttribute(
688
- t__namespace.JSXNamespacedName(
689
- t__namespace.JSXIdentifier("style"),
690
- t__namespace.JSXIdentifier(t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value)
691
- ),
692
- t__namespace.JSXExpressionContainer(p.value)
693
- )
694
- );
695
- styleAttribute.node.value.expression.properties.splice(index - i - 1, 1);
696
- }
697
- });
698
- if (!styleAttribute.node.value.expression.properties.length)
699
- path.get("openingElement").node.attributes.splice(styleAttribute.key, 1);
700
- }
701
-
702
- // preprocess classList
703
- attributes = path.get("openingElement").get("attributes");
704
- const classListAttribute = attributes.find(
705
- a =>
706
- a.node.name &&
707
- a.node.name.name === "classList" &&
708
- t__namespace.isJSXExpressionContainer(a.node.value) &&
709
- t__namespace.isObjectExpression(a.node.value.expression) &&
710
- !a.node.value.expression.properties.some(
711
- p =>
712
- t__namespace.isSpreadElement(p) ||
713
- p.computed ||
714
- (t__namespace.isStringLiteral(p.key) && (p.key.value.includes(" ") || p.key.value.includes(":")))
715
- )
716
- );
717
- if (classListAttribute) {
718
- let i = 0,
719
- leading = classListAttribute.node.value.expression.leadingComments,
720
- classListProperties = classListAttribute.get("value").get("expression").get("properties");
721
- classListProperties.slice().forEach((propPath, index) => {
722
- const p = propPath.node;
723
- const { confident, value: computed } = propPath.get("value").evaluate();
724
- if (leading) p.value.leadingComments = leading;
725
- if (!confident) {
726
- path
727
- .get("openingElement")
728
- .node.attributes.splice(
729
- classListAttribute.key + ++i,
730
- 0,
731
- t__namespace.JSXAttribute(
732
- t__namespace.JSXNamespacedName(
733
- t__namespace.JSXIdentifier("class"),
734
- t__namespace.JSXIdentifier(t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value)
735
- ),
736
- t__namespace.JSXExpressionContainer(p.value)
737
- )
738
- );
739
- } else if (computed) {
740
- path
741
- .get("openingElement")
742
- .node.attributes.splice(
743
- classListAttribute.key + ++i,
744
- 0,
745
- t__namespace.JSXAttribute(
746
- t__namespace.JSXIdentifier("class"),
747
- t__namespace.stringLiteral(t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value)
748
- )
749
- );
750
- }
751
- classListProperties.splice(index - i - 1, 1);
752
- });
753
- if (!classListProperties.length)
754
- path.get("openingElement").node.attributes.splice(classListAttribute.key, 1);
755
- }
756
-
757
- // combine class properties
758
- attributes = path.get("openingElement").get("attributes");
759
- const classAttributes = attributes.filter(
760
- a => a.node.name && (a.node.name.name === "class" || a.node.name.name === "className")
761
- );
762
- if (classAttributes.length > 1) {
763
- const first = classAttributes[0].node,
764
- values = [],
765
- quasis = [t__namespace.TemplateElement({ raw: "" })];
766
- for (let i = 0; i < classAttributes.length; i++) {
767
- const attr = classAttributes[i].node,
768
- isLast = i === classAttributes.length - 1;
769
- if (!t__namespace.isJSXExpressionContainer(attr.value)) {
770
- const prev = quasis.pop();
771
- quasis.push(
772
- t__namespace.TemplateElement({
773
- raw: (prev ? prev.value.raw : "") + `${attr.value.value}` + (isLast ? "" : " ")
774
- })
775
- );
776
- } else {
777
- values.push(t__namespace.logicalExpression("||", attr.value.expression, t__namespace.stringLiteral("")));
778
- quasis.push(t__namespace.TemplateElement({ raw: isLast ? "" : " " }));
779
- }
780
- i && attributes.splice(attributes.indexOf(classAttributes[i]), 1);
781
- }
782
- if (values.length) first.value = t__namespace.JSXExpressionContainer(t__namespace.TemplateLiteral(quasis, values));
783
- else first.value = t__namespace.stringLiteral(quasis[0].value.raw);
784
- }
785
- path.get("openingElement").set(
786
- "attributes",
787
- attributes.map(a => a.node)
788
- );
789
-
790
- path
791
- .get("openingElement")
792
- .get("attributes")
793
- .forEach(attribute => {
794
- const node = attribute.node;
795
- if (t__namespace.isJSXSpreadAttribute(node)) {
796
- results.exprs.push(
797
- t__namespace.expressionStatement(
798
- t__namespace.callExpression(registerImportMethod(attribute, "spread"), [
799
- elem,
800
- isDynamic(attribute.get("argument"), {
801
- checkMember: true
802
- })
803
- ? t__namespace.isCallExpression(node.argument) && !node.argument.arguments.length
804
- ? node.argument.callee
805
- : t__namespace.arrowFunctionExpression([], node.argument)
806
- : node.argument,
807
- t__namespace.booleanLiteral(isSVG),
808
- t__namespace.booleanLiteral(hasChildren)
809
- ])
810
- )
811
- );
812
- //NOTE: can't be checked at compile time so add to compiled output
813
- hasHydratableEvent = true;
814
- return;
815
- }
816
-
817
- let value = node.value,
818
- key = t__namespace.isJSXNamespacedName(node.name)
819
- ? `${node.name.namespace.name}:${node.name.name.name}`
820
- : node.name.name,
821
- reservedNameSpace =
822
- t__namespace.isJSXNamespacedName(node.name) && reservedNameSpaces.has(node.name.namespace.name);
823
- if (t__namespace.isJSXExpressionContainer(value) && !key.startsWith("use:")) {
824
- const evaluated = attribute.get("value").get("expression").evaluate().value;
825
- let type;
826
- if (
827
- evaluated !== undefined &&
828
- ((type = typeof evaluated) === "string" || type === "number")
829
- ) {
830
- value = t__namespace.stringLiteral(String(evaluated));
831
- }
832
- }
833
- if (
834
- t__namespace.isJSXNamespacedName(node.name) &&
835
- reservedNameSpace &&
836
- !t__namespace.isJSXExpressionContainer(value)
837
- ) {
838
- node.value = value = t__namespace.JSXExpressionContainer(value || t__namespace.JSXEmptyExpression());
839
- }
840
- if (
841
- t__namespace.isJSXExpressionContainer(value) &&
842
- (reservedNameSpace ||
843
- !(t__namespace.isStringLiteral(value.expression) || t__namespace.isNumericLiteral(value.expression)))
844
- ) {
845
- if (key === "ref") {
846
- // Normalize expressions for non-null and type-as
847
- while (
848
- t__namespace.isTSNonNullExpression(value.expression) ||
849
- t__namespace.isTSAsExpression(value.expression)
850
- ) {
851
- value.expression = value.expression.expression;
852
- }
853
- let binding,
854
- isFunction =
855
- t__namespace.isIdentifier(value.expression) &&
856
- (binding = path.scope.getBinding(value.expression.name)) &&
857
- binding.kind === "const";
858
- if (!isFunction && t__namespace.isLVal(value.expression)) {
859
- const refIdentifier = path.scope.generateUidIdentifier("_ref$");
860
- results.exprs.unshift(
861
- t__namespace.variableDeclaration("const", [
862
- t__namespace.variableDeclarator(refIdentifier, value.expression)
863
- ]),
864
- t__namespace.expressionStatement(
865
- t__namespace.conditionalExpression(
866
- t__namespace.binaryExpression(
867
- "===",
868
- t__namespace.unaryExpression("typeof", refIdentifier),
869
- t__namespace.stringLiteral("function")
870
- ),
871
- t__namespace.callExpression(refIdentifier, [elem]),
872
- t__namespace.assignmentExpression("=", value.expression, elem)
873
- )
874
- )
875
- );
876
- } else if (isFunction || t__namespace.isFunction(value.expression)) {
877
- results.exprs.unshift(
878
- t__namespace.expressionStatement(t__namespace.callExpression(value.expression, [elem]))
879
- );
880
- } else if (t__namespace.isCallExpression(value.expression)) {
881
- const refIdentifier = path.scope.generateUidIdentifier("_ref$");
882
- results.exprs.unshift(
883
- t__namespace.variableDeclaration("const", [
884
- t__namespace.variableDeclarator(refIdentifier, value.expression)
885
- ]),
886
- t__namespace.expressionStatement(
887
- t__namespace.logicalExpression(
888
- "&&",
889
- t__namespace.binaryExpression(
890
- "===",
891
- t__namespace.unaryExpression("typeof", refIdentifier),
892
- t__namespace.stringLiteral("function")
893
- ),
894
- t__namespace.callExpression(refIdentifier, [elem])
895
- )
896
- )
897
- );
898
- }
899
- } else if (key.startsWith("use:")) {
900
- // Some trick to treat JSXIdentifier as Identifier
901
- node.name.name.type = 'Identifier';
902
- results.exprs.unshift(
903
- t__namespace.expressionStatement(
904
- t__namespace.callExpression(node.name.name, [
905
- elem,
906
- t__namespace.arrowFunctionExpression(
907
- [],
908
- t__namespace.isJSXEmptyExpression(value.expression)
909
- ? t__namespace.booleanLiteral(true)
910
- : value.expression
911
- )
912
- ])
913
- )
914
- );
915
- } else if (key === "children") {
916
- children = value;
917
- } else if (key.startsWith("on")) {
918
- const ev = toEventName(key);
919
- if (key.startsWith("on:") || key.startsWith("oncapture:")) {
920
- const listenerOptions = [t__namespace.stringLiteral(key.split(":")[1]), value.expression];
921
- results.exprs.push(
922
- t__namespace.expressionStatement(
923
- t__namespace.callExpression(
924
- t__namespace.memberExpression(elem, t__namespace.identifier("addEventListener")),
925
- key.startsWith("oncapture:")
926
- ? listenerOptions.concat(t__namespace.booleanLiteral(true))
927
- : listenerOptions
928
- )
929
- )
930
- );
931
- } else if (
932
- config.delegateEvents &&
933
- (DelegatedEvents.has(ev) || config.delegatedEvents.indexOf(ev) !== -1)
934
- ) {
935
- // can only hydrate delegated events
936
- hasHydratableEvent = true;
937
- const events =
938
- attribute.scope.getProgramParent().data.events ||
939
- (attribute.scope.getProgramParent().data.events = new Set());
940
- events.add(ev);
941
- let handler = value.expression;
942
- const resolveable = detectResolvableEventHandler(attribute, handler);
943
- if (t__namespace.isArrayExpression(handler)) {
944
- if (handler.elements.length > 1) {
945
- results.exprs.unshift(
946
- t__namespace.expressionStatement(
947
- t__namespace.assignmentExpression(
948
- "=",
949
- t__namespace.memberExpression(elem, t__namespace.identifier(`$$${ev}Data`)),
950
- handler.elements[1]
951
- )
952
- )
953
- );
954
- }
955
- handler = handler.elements[0];
956
- results.exprs.unshift(
957
- t__namespace.expressionStatement(
958
- t__namespace.assignmentExpression(
959
- "=",
960
- t__namespace.memberExpression(elem, t__namespace.identifier(`$$${ev}`)),
961
- handler
962
- )
963
- )
964
- );
965
- } else if (t__namespace.isFunction(handler) || resolveable) {
966
- results.exprs.unshift(
967
- t__namespace.expressionStatement(
968
- t__namespace.assignmentExpression(
969
- "=",
970
- t__namespace.memberExpression(elem, t__namespace.identifier(`$$${ev}`)),
971
- handler
972
- )
973
- )
974
- );
975
- } else {
976
- results.exprs.unshift(
977
- t__namespace.expressionStatement(
978
- t__namespace.callExpression(registerImportMethod(path, "addEventListener"), [
979
- elem,
980
- t__namespace.stringLiteral(ev),
981
- handler,
982
- t__namespace.booleanLiteral(true)
983
- ])
984
- )
985
- );
986
- }
987
- } else {
988
- let handler = value.expression;
989
- const resolveable = detectResolvableEventHandler(attribute, handler);
990
- if (t__namespace.isArrayExpression(handler)) {
991
- if (handler.elements.length > 1) {
992
- handler = t__namespace.arrowFunctionExpression(
993
- [t__namespace.identifier("e")],
994
- t__namespace.callExpression(handler.elements[0], [handler.elements[1], t__namespace.identifier("e")])
995
- );
996
- } else handler = handler.elements[0];
997
- results.exprs.unshift(
998
- t__namespace.expressionStatement(
999
- t__namespace.callExpression(t__namespace.memberExpression(elem, t__namespace.identifier("addEventListener")), [
1000
- t__namespace.stringLiteral(ev),
1001
- handler
1002
- ])
1003
- )
1004
- );
1005
- } else if (t__namespace.isFunction(handler) || resolveable) {
1006
- results.exprs.unshift(
1007
- t__namespace.expressionStatement(
1008
- t__namespace.callExpression(t__namespace.memberExpression(elem, t__namespace.identifier("addEventListener")), [
1009
- t__namespace.stringLiteral(ev),
1010
- handler
1011
- ])
1012
- )
1013
- );
1014
- } else {
1015
- results.exprs.unshift(
1016
- t__namespace.expressionStatement(
1017
- t__namespace.callExpression(registerImportMethod(path, "addEventListener"), [
1018
- elem,
1019
- t__namespace.stringLiteral(ev),
1020
- handler
1021
- ])
1022
- )
1023
- );
1024
- }
1025
- }
1026
- } else if (
1027
- config.effectWrapper &&
1028
- isDynamic(attribute.get("value").get("expression"), {
1029
- checkMember: true
1030
- })
1031
- ) {
1032
- let nextElem = elem;
1033
- if (key === "textContent") {
1034
- nextElem = attribute.scope.generateUidIdentifier("el$");
1035
- children = t__namespace.JSXText(" ");
1036
- children.extra = { raw: " ", rawValue: " " };
1037
- results.decl.push(
1038
- t__namespace.variableDeclarator(nextElem, t__namespace.memberExpression(elem, t__namespace.identifier("firstChild")))
1039
- );
1040
- }
1041
- results.dynamics.push({ elem: nextElem, key, value: value.expression, isSVG, isCE });
1042
- } else {
1043
- results.exprs.push(
1044
- t__namespace.expressionStatement(setAttr$2(attribute, elem, key, value.expression, { isSVG, isCE }))
1045
- );
1046
- }
1047
- } else {
1048
- if (config.hydratable && key === "$ServerOnly") {
1049
- results.skipTemplate = true;
1050
- return;
1051
- }
1052
- if (t__namespace.isJSXExpressionContainer(value)) value = value.expression;
1053
- key = Aliases[key] || key;
1054
- if (value && ChildProperties.has(key)) {
1055
- results.exprs.push(
1056
- t__namespace.expressionStatement(setAttr$2(attribute, elem, key, value, { isSVG, isCE }))
1057
- );
1058
- } else {
1059
- !isSVG && (key = key.toLowerCase());
1060
- results.template += ` ${key}`;
1061
- results.template += value ? `="${escapeBackticks(value.value)}"` : "";
1062
- }
1063
- }
1064
- });
1065
- if (!hasChildren && children) {
1066
- path.node.children.push(children);
1067
- }
1068
-
1069
- results.hasHydratableEvent = results.hasHydratableEvent || hasHydratableEvent;
1070
- }
1071
-
1072
- function transformChildren$2(path, results, config) {
1073
- let tempPath = results.id && results.id.name,
1074
- tagName = getTagName(path.node),
1075
- nextPlaceholder,
1076
- i = 0;
1077
- const filteredChildren = filterChildren(path.get("children")),
1078
- childNodes = filteredChildren
1079
- .map(
1080
- (child, index) =>
1081
- transformNode(child, {
1082
- skipId: !results.id || !detectExpressions(filteredChildren, index, config)
1083
- })
1084
- // combine adjacent textNodes
1085
- )
1086
- .reduce((memo, child) => {
1087
- if (!child) return memo;
1088
- const i = memo.length;
1089
- if (child.text && i && memo[i - 1].text) {
1090
- memo[i - 1].template += child.template;
1091
- } else memo.push(child);
1092
- return memo;
1093
- }, []);
1094
-
1095
- childNodes.forEach((child, index) => {
1096
- if (!child) return;
1097
- results.template += child.template;
1098
- if (child.id) {
1099
- if (child.tagName === "head") return;
1100
- if (config.hydratable && tagName === "html") {
1101
- registerImportMethod(path, "getNextMatch");
1102
- }
1103
- const walk = t__namespace.memberExpression(
1104
- t__namespace.identifier(tempPath),
1105
- t__namespace.identifier(i === 0 ? "firstChild" : "nextSibling")
1106
- );
1107
- results.decl.push(
1108
- t__namespace.variableDeclarator(
1109
- child.id,
1110
- config.hydratable && tagName === "html"
1111
- ? t__namespace.callExpression(registerImportMethod(path, "getNextMatch"), [
1112
- walk,
1113
- t__namespace.stringLiteral(child.tagName)
1114
- ])
1115
- : walk
1116
- )
1117
- );
1118
- results.decl.push(...child.decl);
1119
- results.exprs.push(...child.exprs);
1120
- results.dynamics.push(...child.dynamics);
1121
- results.hasHydratableEvent = results.hasHydratableEvent || child.hasHydratableEvent;
1122
- tempPath = child.id.name;
1123
- nextPlaceholder = null;
1124
- i++;
1125
- } else if (child.exprs.length) {
1126
- const insert = registerImportMethod(path, "insert");
1127
- const multi = checkLength(filteredChildren),
1128
- markers = config.hydratable && multi;
1129
- // boxed by textNodes
1130
- if (markers || wrappedByText(childNodes, index)) {
1131
- let exprId, contentId;
1132
- if (markers) tempPath = createPlaceholder(path, results, tempPath, i++, "#")[0].name;
1133
- if (nextPlaceholder) {
1134
- exprId = nextPlaceholder;
1135
- } else {
1136
- [exprId, contentId] = createPlaceholder(path, results, tempPath, i++, markers ? "/" : "");
1137
- }
1138
- if (!markers) nextPlaceholder = exprId;
1139
- results.exprs.push(
1140
- t__namespace.expressionStatement(
1141
- t__namespace.callExpression(
1142
- insert,
1143
- contentId
1144
- ? [results.id, child.exprs[0], exprId, contentId]
1145
- : [results.id, child.exprs[0], exprId]
1146
- )
1147
- )
1148
- );
1149
- tempPath = exprId.name;
1150
- } else if (multi) {
1151
- results.exprs.push(
1152
- t__namespace.expressionStatement(
1153
- t__namespace.callExpression(insert, [
1154
- results.id,
1155
- child.exprs[0],
1156
- nextChild$1(childNodes, index) || t__namespace.nullLiteral()
1157
- ])
1158
- )
1159
- );
1160
- } else {
1161
- results.exprs.push(
1162
- t__namespace.expressionStatement(
1163
- t__namespace.callExpression(
1164
- insert,
1165
- [results.id, child.exprs[0]]
1166
- )
1167
- )
1168
- );
1169
- }
1170
- } else nextPlaceholder = null;
1171
- });
1172
- }
1173
-
1174
- function createPlaceholder(path, results, tempPath, i, char) {
1175
- const exprId = path.scope.generateUidIdentifier("el$"),
1176
- config = getConfig(path);
1177
- let contentId;
1178
- results.template += `<!${char}>`;
1179
- if (config.hydratable && char === "/") {
1180
- contentId = path.scope.generateUidIdentifier("co$");
1181
- results.decl.push(
1182
- t__namespace.variableDeclarator(
1183
- t__namespace.arrayPattern([exprId, contentId]),
1184
- t__namespace.callExpression(registerImportMethod(path, "getNextMarker"), [
1185
- t__namespace.memberExpression(t__namespace.identifier(tempPath), t__namespace.identifier("nextSibling"))
1186
- ])
1187
- )
1188
- );
1189
- } else
1190
- results.decl.push(
1191
- t__namespace.variableDeclarator(
1192
- exprId,
1193
- t__namespace.memberExpression(
1194
- t__namespace.identifier(tempPath),
1195
- t__namespace.identifier(i === 0 ? "firstChild" : "nextSibling")
1196
- )
1197
- )
1198
- );
1199
- return [exprId, contentId];
1200
- }
1201
-
1202
- function nextChild$1(children, index) {
1203
- return children[index + 1] && (children[index + 1].id || nextChild$1(children, index + 1));
1204
- }
1205
-
1206
- // reduce unnecessary refs
1207
- function detectExpressions(children, index, config) {
1208
- if (children[index - 1]) {
1209
- const node = children[index - 1].node;
1210
- if (
1211
- t__namespace.isJSXExpressionContainer(node) &&
1212
- !t__namespace.isJSXEmptyExpression(node.expression) &&
1213
- !getStaticExpression(children[index - 1])
1214
- )
1215
- return true;
1216
- let tagName;
1217
- if (t__namespace.isJSXElement(node) && (tagName = getTagName(node)) && isComponent(tagName)) return true;
1218
- }
1219
- for (let i = index; i < children.length; i++) {
1220
- const child = children[i].node;
1221
- if (t__namespace.isJSXExpressionContainer(child)) {
1222
- if (!t__namespace.isJSXEmptyExpression(child.expression) && !getStaticExpression(children[i]))
1223
- return true;
1224
- } else if (t__namespace.isJSXElement(child)) {
1225
- const tagName = getTagName(child);
1226
- if (isComponent(tagName)) return true;
1227
- if (config.contextToCustomElements && (tagName === "slot" || tagName.indexOf("-") > -1))
1228
- return true;
1229
- if (
1230
- child.openingElement.attributes.some(
1231
- attr =>
1232
- t__namespace.isJSXSpreadAttribute(attr) ||
1233
- ["textContent", "innerHTML", "innerText"].includes(attr.name.name) ||
1234
- (attr.name.namespace && attr.name.namespace.name === "use") ||
1235
- (t__namespace.isJSXExpressionContainer(attr.value) &&
1236
- !(
1237
- t__namespace.isStringLiteral(attr.value.expression) ||
1238
- t__namespace.isNumericLiteral(attr.value.expression)
1239
- ))
1240
- )
1241
- )
1242
- return true;
1243
- const nextChildren = filterChildren(children[i].get("children"));
1244
- if (nextChildren.length) if (detectExpressions(nextChildren, 0, config)) return true;
1245
- }
1246
- }
1247
- }
1248
-
1249
- function contextToCustomElement(path, results) {
1250
- results.exprs.push(
1251
- t__namespace.expressionStatement(
1252
- t__namespace.assignmentExpression(
1253
- "=",
1254
- t__namespace.memberExpression(results.id, t__namespace.identifier("_$owner")),
1255
- t__namespace.callExpression(registerImportMethod(path, "getOwner"), [])
1256
- )
1257
- )
1258
- );
523
+ function transformElement$3(path, info) {
524
+ let tagName = getTagName(path.node),
525
+ config = getConfig(path),
526
+ wrapSVG = info.topLevel && tagName != "svg" && SVGElements.has(tagName),
527
+ voidTag = VoidElements.indexOf(tagName) > -1,
528
+ results = {
529
+ template: `<${tagName}`,
530
+ decl: [],
531
+ exprs: [],
532
+ dynamics: [],
533
+ postExprs: [],
534
+ isSVG: wrapSVG,
535
+ tagName,
536
+ renderer: "dom"
537
+ };
538
+ if (tagName === "html" && config.hydratable) results.skipTemplate = true;
539
+ if (wrapSVG) results.template = "<svg>" + results.template;
540
+ if (!info.skipId) results.id = path.scope.generateUidIdentifier("el$");
541
+ transformAttributes$2(path, results);
542
+ if (config.contextToCustomElements && (tagName === "slot" || tagName.indexOf("-") > -1)) {
543
+ contextToCustomElement(path, results);
544
+ }
545
+ results.template += ">";
546
+ if (!voidTag) {
547
+ transformChildren$2(path, results, config);
548
+ results.template += `</${tagName}>`;
549
+ }
550
+ if (info.topLevel && config.hydratable && results.hasHydratableEvent) {
551
+ let runHydrationEvents = registerImportMethod(
552
+ path,
553
+ "runHydrationEvents",
554
+ getRendererConfig(path, "dom").moduleName
555
+ );
556
+ results.postExprs.push(t__namespace.expressionStatement(t__namespace.callExpression(runHydrationEvents, [])));
557
+ }
558
+ if (wrapSVG) results.template += "</svg>";
559
+ return results;
560
+ }
561
+
562
+ function setAttr$2(path, elem, name, value, { isSVG, dynamic, prevId, isCE }) {
563
+ // pull out namespace
564
+ const config = getConfig(path);
565
+ let parts, namespace;
566
+ if ((parts = name.split(":")) && parts[1] && reservedNameSpaces.has(parts[0])) {
567
+ name = parts[1];
568
+ namespace = parts[0];
569
+ }
570
+
571
+ if (namespace === "style") {
572
+ return t__namespace.callExpression(
573
+ t__namespace.memberExpression(
574
+ t__namespace.memberExpression(elem, t__namespace.identifier("style")),
575
+ t__namespace.identifier("setProperty")
576
+ ),
577
+ [t__namespace.stringLiteral(name), value]
578
+ );
579
+ }
580
+
581
+ if (namespace === "class") {
582
+ return t__namespace.callExpression(
583
+ t__namespace.memberExpression(
584
+ t__namespace.memberExpression(elem, t__namespace.identifier("classList")),
585
+ t__namespace.identifier("toggle")
586
+ ),
587
+ [t__namespace.stringLiteral(name), value]
588
+ );
589
+ }
590
+
591
+ if (name === "style") {
592
+ return t__namespace.callExpression(registerImportMethod(path, "style", getRendererConfig(path, "dom").moduleName), prevId ? [elem, value, prevId] : [elem, value]);
593
+ }
594
+
595
+ if (!isSVG && name === "class") {
596
+ return t__namespace.assignmentExpression("=", t__namespace.memberExpression(elem, t__namespace.identifier("className")), value);
597
+ }
598
+
599
+ if (name === "classList") {
600
+ return t__namespace.callExpression(registerImportMethod(
601
+ path,
602
+ "classList",
603
+ getRendererConfig(path, "dom").moduleName
604
+ ), prevId ? [elem, value, prevId] : [elem, value]);
605
+ }
606
+
607
+ if (config.hydratable && name === "innerHTML") {
608
+ return t__namespace.callExpression(
609
+ registerImportMethod(path, "innerHTML"),
610
+ [elem, value]
611
+ );
612
+ }
613
+
614
+ if (dynamic && name === "textContent") {
615
+ return t__namespace.assignmentExpression("=", t__namespace.memberExpression(elem, t__namespace.identifier("data")), value);
616
+ }
617
+
618
+ const isChildProp = ChildProperties.has(name);
619
+ const isProp = Properties.has(name);
620
+ const alias = PropAliases[name];
621
+ if (namespace !== "attr" && (isChildProp || (!isSVG && isProp) || isCE || namespace === "prop")) {
622
+ if (isCE && !isChildProp && !isProp && namespace !== "prop") name = toPropertyName(name);
623
+ return t__namespace.assignmentExpression(
624
+ "=",
625
+ t__namespace.memberExpression(elem, t__namespace.identifier(alias || name)),
626
+ value
627
+ );
628
+ }
629
+
630
+ let isNameSpaced = name.indexOf(":") > -1;
631
+ name = Aliases[name] || name;
632
+ !isSVG && (name = name.toLowerCase());
633
+ const ns = isNameSpaced && SVGNamespace[name.split(":")[0]];
634
+ if (ns) {
635
+ return t__namespace.callExpression(registerImportMethod(
636
+ path,
637
+ "setAttributeNS",
638
+ getRendererConfig(path, "dom").moduleName
639
+ ), [
640
+ elem,
641
+ t__namespace.stringLiteral(ns),
642
+ t__namespace.stringLiteral(name),
643
+ value
644
+ ]);
645
+ } else {
646
+ return t__namespace.callExpression(registerImportMethod(
647
+ path,
648
+ "setAttribute",
649
+ getRendererConfig(path, "dom").moduleName
650
+ ), [elem, t__namespace.stringLiteral(name), value]);
651
+ }
652
+ }
653
+
654
+ function detectResolvableEventHandler(attribute, handler) {
655
+ while (t__namespace.isIdentifier(handler)) {
656
+ const lookup = attribute.scope.getBinding(handler.name);
657
+ if (lookup) {
658
+ if (t__namespace.isVariableDeclarator(lookup.path.node)) {
659
+ handler = lookup.path.node.init;
660
+ } else if (t__namespace.isFunctionDeclaration(lookup.path.node)) {
661
+ return true;
662
+ } else return false;
663
+ } else return false;
664
+ }
665
+ return t__namespace.isFunction(handler);
666
+ }
667
+
668
+ function transformAttributes$2(path, results) {
669
+ let elem = results.id,
670
+ hasHydratableEvent = false,
671
+ children,
672
+ attributes = path.get("openingElement").get("attributes");
673
+ const tagName = getTagName(path.node),
674
+ isSVG = SVGElements.has(tagName),
675
+ isCE = tagName.includes("-"),
676
+ hasChildren = path.node.children.length > 0,
677
+ config = getConfig(path);
678
+
679
+ // preprocess styles
680
+ const styleAttribute = attributes.find(
681
+ a =>
682
+ a.node.name &&
683
+ a.node.name.name === "style" &&
684
+ t__namespace.isJSXExpressionContainer(a.node.value) &&
685
+ t__namespace.isObjectExpression(a.node.value.expression) &&
686
+ !a.node.value.expression.properties.some(p => t__namespace.isSpreadElement(p))
687
+ );
688
+ if (styleAttribute) {
689
+ let i = 0,
690
+ leading = styleAttribute.node.value.expression.leadingComments;
691
+ styleAttribute.node.value.expression.properties.slice().forEach((p, index) => {
692
+ if (!p.computed) {
693
+ if (leading) p.value.leadingComments = leading;
694
+ path
695
+ .get("openingElement")
696
+ .node.attributes.splice(
697
+ styleAttribute.key + ++i,
698
+ 0,
699
+ t__namespace.JSXAttribute(
700
+ t__namespace.JSXNamespacedName(
701
+ t__namespace.JSXIdentifier("style"),
702
+ t__namespace.JSXIdentifier(t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value)
703
+ ),
704
+ t__namespace.JSXExpressionContainer(p.value)
705
+ )
706
+ );
707
+ styleAttribute.node.value.expression.properties.splice(index - i - 1, 1);
708
+ }
709
+ });
710
+ if (!styleAttribute.node.value.expression.properties.length)
711
+ path.get("openingElement").node.attributes.splice(styleAttribute.key, 1);
712
+ }
713
+
714
+ // preprocess classList
715
+ attributes = path.get("openingElement").get("attributes");
716
+ const classListAttribute = attributes.find(
717
+ a =>
718
+ a.node.name &&
719
+ a.node.name.name === "classList" &&
720
+ t__namespace.isJSXExpressionContainer(a.node.value) &&
721
+ t__namespace.isObjectExpression(a.node.value.expression) &&
722
+ !a.node.value.expression.properties.some(
723
+ p =>
724
+ t__namespace.isSpreadElement(p) ||
725
+ p.computed ||
726
+ (t__namespace.isStringLiteral(p.key) && (p.key.value.includes(" ") || p.key.value.includes(":")))
727
+ )
728
+ );
729
+ if (classListAttribute) {
730
+ let i = 0,
731
+ leading = classListAttribute.node.value.expression.leadingComments,
732
+ classListProperties = classListAttribute.get("value").get("expression").get("properties");
733
+ classListProperties.slice().forEach((propPath, index) => {
734
+ const p = propPath.node;
735
+ const { confident, value: computed } = propPath.get("value").evaluate();
736
+ if (leading) p.value.leadingComments = leading;
737
+ if (!confident) {
738
+ path
739
+ .get("openingElement")
740
+ .node.attributes.splice(
741
+ classListAttribute.key + ++i,
742
+ 0,
743
+ t__namespace.JSXAttribute(
744
+ t__namespace.JSXNamespacedName(
745
+ t__namespace.JSXIdentifier("class"),
746
+ t__namespace.JSXIdentifier(t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value)
747
+ ),
748
+ t__namespace.JSXExpressionContainer(p.value)
749
+ )
750
+ );
751
+ } else if (computed) {
752
+ path
753
+ .get("openingElement")
754
+ .node.attributes.splice(
755
+ classListAttribute.key + ++i,
756
+ 0,
757
+ t__namespace.JSXAttribute(
758
+ t__namespace.JSXIdentifier("class"),
759
+ t__namespace.stringLiteral(t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value)
760
+ )
761
+ );
762
+ }
763
+ classListProperties.splice(index - i - 1, 1);
764
+ });
765
+ if (!classListProperties.length)
766
+ path.get("openingElement").node.attributes.splice(classListAttribute.key, 1);
767
+ }
768
+
769
+ // combine class properties
770
+ attributes = path.get("openingElement").get("attributes");
771
+ const classAttributes = attributes.filter(
772
+ a => a.node.name && (a.node.name.name === "class" || a.node.name.name === "className")
773
+ );
774
+ if (classAttributes.length > 1) {
775
+ const first = classAttributes[0].node,
776
+ values = [],
777
+ quasis = [t__namespace.TemplateElement({ raw: "" })];
778
+ for (let i = 0; i < classAttributes.length; i++) {
779
+ const attr = classAttributes[i].node,
780
+ isLast = i === classAttributes.length - 1;
781
+ if (!t__namespace.isJSXExpressionContainer(attr.value)) {
782
+ const prev = quasis.pop();
783
+ quasis.push(
784
+ t__namespace.TemplateElement({
785
+ raw: (prev ? prev.value.raw : "") + `${attr.value.value}` + (isLast ? "" : " ")
786
+ })
787
+ );
788
+ } else {
789
+ values.push(t__namespace.logicalExpression("||", attr.value.expression, t__namespace.stringLiteral("")));
790
+ quasis.push(t__namespace.TemplateElement({ raw: isLast ? "" : " " }));
791
+ }
792
+ i && attributes.splice(attributes.indexOf(classAttributes[i]), 1);
793
+ }
794
+ if (values.length) first.value = t__namespace.JSXExpressionContainer(t__namespace.TemplateLiteral(quasis, values));
795
+ else first.value = t__namespace.stringLiteral(quasis[0].value.raw);
796
+ }
797
+ path.get("openingElement").set(
798
+ "attributes",
799
+ attributes.map(a => a.node)
800
+ );
801
+
802
+ path
803
+ .get("openingElement")
804
+ .get("attributes")
805
+ .forEach(attribute => {
806
+ const node = attribute.node;
807
+ if (t__namespace.isJSXSpreadAttribute(node)) {
808
+ results.exprs.push(
809
+ t__namespace.expressionStatement(
810
+ t__namespace.callExpression(registerImportMethod(
811
+ attribute,
812
+ "spread",
813
+ getRendererConfig(path, "dom").moduleName
814
+ ), [
815
+ elem,
816
+ isDynamic(attribute.get("argument"), {
817
+ checkMember: true
818
+ })
819
+ ? t__namespace.isCallExpression(node.argument) && !node.argument.arguments.length
820
+ ? node.argument.callee
821
+ : t__namespace.arrowFunctionExpression([], node.argument)
822
+ : node.argument,
823
+ t__namespace.booleanLiteral(isSVG),
824
+ t__namespace.booleanLiteral(hasChildren)
825
+ ])
826
+ )
827
+ );
828
+ //NOTE: can't be checked at compile time so add to compiled output
829
+ hasHydratableEvent = true;
830
+ return;
831
+ }
832
+
833
+ let value = node.value,
834
+ key = t__namespace.isJSXNamespacedName(node.name)
835
+ ? `${node.name.namespace.name}:${node.name.name.name}`
836
+ : node.name.name,
837
+ reservedNameSpace =
838
+ t__namespace.isJSXNamespacedName(node.name) && reservedNameSpaces.has(node.name.namespace.name);
839
+ if (t__namespace.isJSXExpressionContainer(value) && !key.startsWith("use:")) {
840
+ const evaluated = attribute.get("value").get("expression").evaluate().value;
841
+ let type;
842
+ if (
843
+ evaluated !== undefined &&
844
+ ((type = typeof evaluated) === "string" || type === "number")
845
+ ) {
846
+ value = t__namespace.stringLiteral(String(evaluated));
847
+ }
848
+ }
849
+ if (
850
+ t__namespace.isJSXNamespacedName(node.name) &&
851
+ reservedNameSpace &&
852
+ !t__namespace.isJSXExpressionContainer(value)
853
+ ) {
854
+ node.value = value = t__namespace.JSXExpressionContainer(value || t__namespace.JSXEmptyExpression());
855
+ }
856
+ if (
857
+ t__namespace.isJSXExpressionContainer(value) &&
858
+ (reservedNameSpace ||
859
+ !(t__namespace.isStringLiteral(value.expression) || t__namespace.isNumericLiteral(value.expression)))
860
+ ) {
861
+ if (key === "ref") {
862
+ // Normalize expressions for non-null and type-as
863
+ while (
864
+ t__namespace.isTSNonNullExpression(value.expression) ||
865
+ t__namespace.isTSAsExpression(value.expression)
866
+ ) {
867
+ value.expression = value.expression.expression;
868
+ }
869
+ let binding,
870
+ isFunction =
871
+ t__namespace.isIdentifier(value.expression) &&
872
+ (binding = path.scope.getBinding(value.expression.name)) &&
873
+ binding.kind === "const";
874
+ if (!isFunction && t__namespace.isLVal(value.expression)) {
875
+ const refIdentifier = path.scope.generateUidIdentifier("_ref$");
876
+ results.exprs.unshift(
877
+ t__namespace.variableDeclaration("const", [
878
+ t__namespace.variableDeclarator(refIdentifier, value.expression)
879
+ ]),
880
+ t__namespace.expressionStatement(
881
+ t__namespace.conditionalExpression(
882
+ t__namespace.binaryExpression(
883
+ "===",
884
+ t__namespace.unaryExpression("typeof", refIdentifier),
885
+ t__namespace.stringLiteral("function")
886
+ ),
887
+ t__namespace.callExpression(refIdentifier, [elem]),
888
+ t__namespace.assignmentExpression("=", value.expression, elem)
889
+ )
890
+ )
891
+ );
892
+ } else if (isFunction || t__namespace.isFunction(value.expression)) {
893
+ results.exprs.unshift(
894
+ t__namespace.expressionStatement(t__namespace.callExpression(value.expression, [elem]))
895
+ );
896
+ } else if (t__namespace.isCallExpression(value.expression)) {
897
+ const refIdentifier = path.scope.generateUidIdentifier("_ref$");
898
+ results.exprs.unshift(
899
+ t__namespace.variableDeclaration("const", [
900
+ t__namespace.variableDeclarator(refIdentifier, value.expression)
901
+ ]),
902
+ t__namespace.expressionStatement(
903
+ t__namespace.logicalExpression(
904
+ "&&",
905
+ t__namespace.binaryExpression(
906
+ "===",
907
+ t__namespace.unaryExpression("typeof", refIdentifier),
908
+ t__namespace.stringLiteral("function")
909
+ ),
910
+ t__namespace.callExpression(refIdentifier, [elem])
911
+ )
912
+ )
913
+ );
914
+ }
915
+ } else if (key.startsWith("use:")) {
916
+ // Some trick to treat JSXIdentifier as Identifier
917
+ node.name.name.type = 'Identifier';
918
+ results.exprs.unshift(
919
+ 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
+ ])
929
+ )
930
+ );
931
+ } else if (key === "children") {
932
+ children = value;
933
+ } else if (key.startsWith("on")) {
934
+ const ev = toEventName(key);
935
+ if (key.startsWith("on:") || key.startsWith("oncapture:")) {
936
+ const listenerOptions = [t__namespace.stringLiteral(key.split(":")[1]), value.expression];
937
+ results.exprs.push(
938
+ t__namespace.expressionStatement(
939
+ t__namespace.callExpression(
940
+ t__namespace.memberExpression(elem, t__namespace.identifier("addEventListener")),
941
+ key.startsWith("oncapture:")
942
+ ? listenerOptions.concat(t__namespace.booleanLiteral(true))
943
+ : listenerOptions
944
+ )
945
+ )
946
+ );
947
+ } else if (
948
+ config.delegateEvents &&
949
+ (DelegatedEvents.has(ev) || config.delegatedEvents.indexOf(ev) !== -1)
950
+ ) {
951
+ // can only hydrate delegated events
952
+ hasHydratableEvent = true;
953
+ const events =
954
+ attribute.scope.getProgramParent().data.events ||
955
+ (attribute.scope.getProgramParent().data.events = new Set());
956
+ events.add(ev);
957
+ let handler = value.expression;
958
+ const resolveable = detectResolvableEventHandler(attribute, handler);
959
+ if (t__namespace.isArrayExpression(handler)) {
960
+ if (handler.elements.length > 1) {
961
+ results.exprs.unshift(
962
+ t__namespace.expressionStatement(
963
+ t__namespace.assignmentExpression(
964
+ "=",
965
+ t__namespace.memberExpression(elem, t__namespace.identifier(`$$${ev}Data`)),
966
+ handler.elements[1]
967
+ )
968
+ )
969
+ );
970
+ }
971
+ handler = handler.elements[0];
972
+ results.exprs.unshift(
973
+ t__namespace.expressionStatement(
974
+ t__namespace.assignmentExpression(
975
+ "=",
976
+ t__namespace.memberExpression(elem, t__namespace.identifier(`$$${ev}`)),
977
+ handler
978
+ )
979
+ )
980
+ );
981
+ } else if (t__namespace.isFunction(handler) || resolveable) {
982
+ results.exprs.unshift(
983
+ t__namespace.expressionStatement(
984
+ t__namespace.assignmentExpression(
985
+ "=",
986
+ t__namespace.memberExpression(elem, t__namespace.identifier(`$$${ev}`)),
987
+ handler
988
+ )
989
+ )
990
+ );
991
+ } else {
992
+ results.exprs.unshift(
993
+ t__namespace.expressionStatement(
994
+ t__namespace.callExpression(registerImportMethod(
995
+ path,
996
+ "addEventListener",
997
+ getRendererConfig(path, "dom").moduleName
998
+ ), [
999
+ elem,
1000
+ t__namespace.stringLiteral(ev),
1001
+ handler,
1002
+ t__namespace.booleanLiteral(true)
1003
+ ])
1004
+ )
1005
+ );
1006
+ }
1007
+ } else {
1008
+ let handler = value.expression;
1009
+ const resolveable = detectResolvableEventHandler(attribute, handler);
1010
+ if (t__namespace.isArrayExpression(handler)) {
1011
+ if (handler.elements.length > 1) {
1012
+ handler = t__namespace.arrowFunctionExpression(
1013
+ [t__namespace.identifier("e")],
1014
+ t__namespace.callExpression(handler.elements[0], [handler.elements[1], t__namespace.identifier("e")])
1015
+ );
1016
+ } else handler = handler.elements[0];
1017
+ results.exprs.unshift(
1018
+ t__namespace.expressionStatement(
1019
+ t__namespace.callExpression(t__namespace.memberExpression(elem, t__namespace.identifier("addEventListener")), [
1020
+ t__namespace.stringLiteral(ev),
1021
+ handler
1022
+ ])
1023
+ )
1024
+ );
1025
+ } else if (t__namespace.isFunction(handler) || resolveable) {
1026
+ results.exprs.unshift(
1027
+ t__namespace.expressionStatement(
1028
+ t__namespace.callExpression(t__namespace.memberExpression(elem, t__namespace.identifier("addEventListener")), [
1029
+ t__namespace.stringLiteral(ev),
1030
+ handler
1031
+ ])
1032
+ )
1033
+ );
1034
+ } else {
1035
+ results.exprs.unshift(
1036
+ t__namespace.expressionStatement(
1037
+ t__namespace.callExpression(registerImportMethod(
1038
+ path,
1039
+ "addEventListener",
1040
+ getRendererConfig(path, "dom").moduleName
1041
+ ), [elem, t__namespace.stringLiteral(ev), handler])
1042
+ )
1043
+ );
1044
+ }
1045
+ }
1046
+ } else if (
1047
+ config.effectWrapper &&
1048
+ isDynamic(attribute.get("value").get("expression"), {
1049
+ checkMember: true
1050
+ })
1051
+ ) {
1052
+ let nextElem = elem;
1053
+ if (key === "textContent") {
1054
+ nextElem = attribute.scope.generateUidIdentifier("el$");
1055
+ children = t__namespace.JSXText(" ");
1056
+ children.extra = { raw: " ", rawValue: " " };
1057
+ results.decl.push(
1058
+ t__namespace.variableDeclarator(nextElem, t__namespace.memberExpression(elem, t__namespace.identifier("firstChild")))
1059
+ );
1060
+ }
1061
+ results.dynamics.push({ elem: nextElem, key, value: value.expression, isSVG, isCE });
1062
+ } else {
1063
+ results.exprs.push(
1064
+ t__namespace.expressionStatement(setAttr$2(attribute, elem, key, value.expression, { isSVG, isCE }))
1065
+ );
1066
+ }
1067
+ } else {
1068
+ if (config.hydratable && key === "$ServerOnly") {
1069
+ results.skipTemplate = true;
1070
+ return;
1071
+ }
1072
+ if (t__namespace.isJSXExpressionContainer(value)) value = value.expression;
1073
+ key = Aliases[key] || key;
1074
+ if (value && ChildProperties.has(key)) {
1075
+ results.exprs.push(
1076
+ t__namespace.expressionStatement(setAttr$2(attribute, elem, key, value, { isSVG, isCE }))
1077
+ );
1078
+ } else {
1079
+ !isSVG && (key = key.toLowerCase());
1080
+ results.template += ` ${key}`;
1081
+ results.template += value ? `="${escapeBackticks(value.value)}"` : "";
1082
+ }
1083
+ }
1084
+ });
1085
+ if (!hasChildren && children) {
1086
+ path.node.children.push(children);
1087
+ }
1088
+
1089
+ results.hasHydratableEvent = results.hasHydratableEvent || hasHydratableEvent;
1090
+ }
1091
+
1092
+ function transformChildren$2(path, results, config) {
1093
+ let tempPath = results.id && results.id.name,
1094
+ tagName = getTagName(path.node),
1095
+ nextPlaceholder,
1096
+ i = 0;
1097
+ const filteredChildren = filterChildren(path.get("children")),
1098
+ childNodes = filteredChildren
1099
+ .map(
1100
+ (child, index) =>
1101
+ transformNode(child, {
1102
+ skipId: !results.id || !detectExpressions(filteredChildren, index, config)
1103
+ })
1104
+ // combine adjacent textNodes
1105
+ )
1106
+ .reduce((memo, child) => {
1107
+ if (!child) return memo;
1108
+ const i = memo.length;
1109
+ if (child.text && i && memo[i - 1].text) {
1110
+ memo[i - 1].template += child.template;
1111
+ } else memo.push(child);
1112
+ return memo;
1113
+ }, []);
1114
+
1115
+ childNodes.forEach((child, index) => {
1116
+ if (!child) return;
1117
+ if (child.tagName && child.renderer !== "dom") {
1118
+ throw new Error(`<${child.tagName}> is not supported in <${tagName}>.
1119
+ Wrap the usage with a component that would render this element, eg. Canvas`);
1120
+ }
1121
+
1122
+ results.template += child.template;
1123
+ if (child.id) {
1124
+ if (child.tagName === "head") return;
1125
+
1126
+ let getNextMatch;
1127
+ if (config.hydratable && tagName === "html") {
1128
+ getNextMatch = registerImportMethod(
1129
+ path,
1130
+ "getNextMatch",
1131
+ getRendererConfig(path, "dom").moduleName
1132
+ );
1133
+ }
1134
+ const walk = t__namespace.memberExpression(
1135
+ t__namespace.identifier(tempPath),
1136
+ t__namespace.identifier(i === 0 ? "firstChild" : "nextSibling")
1137
+ );
1138
+ results.decl.push(
1139
+ t__namespace.variableDeclarator(
1140
+ child.id,
1141
+ config.hydratable && tagName === "html"
1142
+ ? t__namespace.callExpression(getNextMatch, [walk, t__namespace.stringLiteral(child.tagName)])
1143
+ : walk
1144
+ )
1145
+ );
1146
+ results.decl.push(...child.decl);
1147
+ results.exprs.push(...child.exprs);
1148
+ results.dynamics.push(...child.dynamics);
1149
+ results.hasHydratableEvent = results.hasHydratableEvent || child.hasHydratableEvent;
1150
+ tempPath = child.id.name;
1151
+ nextPlaceholder = null;
1152
+ i++;
1153
+ } else if (child.exprs.length) {
1154
+ let insert = registerImportMethod(path, "insert", getRendererConfig(path, "dom").moduleName);
1155
+ const multi = checkLength(filteredChildren),
1156
+ markers = config.hydratable && multi;
1157
+ // boxed by textNodes
1158
+ if (markers || wrappedByText(childNodes, index)) {
1159
+ let exprId, contentId;
1160
+ if (markers) tempPath = createPlaceholder(path, results, tempPath, i++, "#")[0].name;
1161
+ if (nextPlaceholder) {
1162
+ exprId = nextPlaceholder;
1163
+ } else {
1164
+ [exprId, contentId] = createPlaceholder(path, results, tempPath, i++, markers ? "/" : "");
1165
+ }
1166
+ if (!markers) nextPlaceholder = exprId;
1167
+ results.exprs.push(
1168
+ t__namespace.expressionStatement(
1169
+ t__namespace.callExpression(
1170
+ insert,
1171
+ contentId
1172
+ ? [results.id, child.exprs[0], exprId, contentId]
1173
+ : [results.id, child.exprs[0], exprId]
1174
+ )
1175
+ )
1176
+ );
1177
+ tempPath = exprId.name;
1178
+ } else if (multi) {
1179
+ results.exprs.push(
1180
+ t__namespace.expressionStatement(
1181
+ t__namespace.callExpression(insert, [
1182
+ results.id,
1183
+ child.exprs[0],
1184
+ nextChild$1(childNodes, index) || t__namespace.nullLiteral()
1185
+ ])
1186
+ )
1187
+ );
1188
+ } else {
1189
+ results.exprs.push(
1190
+ t__namespace.expressionStatement(
1191
+ t__namespace.callExpression(
1192
+ insert,
1193
+ [results.id, child.exprs[0]]
1194
+ )
1195
+ )
1196
+ );
1197
+ }
1198
+ } else nextPlaceholder = null;
1199
+ });
1200
+ }
1201
+
1202
+ function createPlaceholder(path, results, tempPath, i, char) {
1203
+ const exprId = path.scope.generateUidIdentifier("el$"),
1204
+ config = getConfig(path);
1205
+ let contentId;
1206
+ results.template += `<!${char}>`;
1207
+ if (config.hydratable && char === "/") {
1208
+ contentId = path.scope.generateUidIdentifier("co$");
1209
+ results.decl.push(
1210
+ t__namespace.variableDeclarator(
1211
+ t__namespace.arrayPattern([exprId, contentId]),
1212
+ t__namespace.callExpression(
1213
+ registerImportMethod(path, "getNextMarker", getRendererConfig(path, "dom").moduleName),
1214
+ [t__namespace.memberExpression(t__namespace.identifier(tempPath), t__namespace.identifier("nextSibling"))]
1215
+ )
1216
+ )
1217
+ );
1218
+ } else
1219
+ results.decl.push(
1220
+ t__namespace.variableDeclarator(
1221
+ exprId,
1222
+ t__namespace.memberExpression(
1223
+ t__namespace.identifier(tempPath),
1224
+ t__namespace.identifier(i === 0 ? "firstChild" : "nextSibling")
1225
+ )
1226
+ )
1227
+ );
1228
+ return [exprId, contentId];
1229
+ }
1230
+
1231
+ function nextChild$1(children, index) {
1232
+ return children[index + 1] && (children[index + 1].id || nextChild$1(children, index + 1));
1233
+ }
1234
+
1235
+ // reduce unnecessary refs
1236
+ function detectExpressions(children, index, config) {
1237
+ if (children[index - 1]) {
1238
+ const node = children[index - 1].node;
1239
+ if (
1240
+ t__namespace.isJSXExpressionContainer(node) &&
1241
+ !t__namespace.isJSXEmptyExpression(node.expression) &&
1242
+ !getStaticExpression(children[index - 1])
1243
+ )
1244
+ return true;
1245
+ let tagName;
1246
+ if (t__namespace.isJSXElement(node) && (tagName = getTagName(node)) && isComponent(tagName)) return true;
1247
+ }
1248
+ for (let i = index; i < children.length; i++) {
1249
+ const child = children[i].node;
1250
+ if (t__namespace.isJSXExpressionContainer(child)) {
1251
+ if (!t__namespace.isJSXEmptyExpression(child.expression) && !getStaticExpression(children[i]))
1252
+ return true;
1253
+ } else if (t__namespace.isJSXElement(child)) {
1254
+ const tagName = getTagName(child);
1255
+ if (isComponent(tagName)) return true;
1256
+ if (config.contextToCustomElements && (tagName === "slot" || tagName.indexOf("-") > -1))
1257
+ return true;
1258
+ if (
1259
+ child.openingElement.attributes.some(
1260
+ attr =>
1261
+ t__namespace.isJSXSpreadAttribute(attr) ||
1262
+ ["textContent", "innerHTML", "innerText"].includes(attr.name.name) ||
1263
+ (attr.name.namespace && attr.name.namespace.name === "use") ||
1264
+ (t__namespace.isJSXExpressionContainer(attr.value) &&
1265
+ !(
1266
+ t__namespace.isStringLiteral(attr.value.expression) ||
1267
+ t__namespace.isNumericLiteral(attr.value.expression)
1268
+ ))
1269
+ )
1270
+ )
1271
+ return true;
1272
+ const nextChildren = filterChildren(children[i].get("children"));
1273
+ if (nextChildren.length) if (detectExpressions(nextChildren, 0, config)) return true;
1274
+ }
1275
+ }
1276
+ }
1277
+
1278
+ function contextToCustomElement(path, results) {
1279
+ results.exprs.push(
1280
+ t__namespace.expressionStatement(
1281
+ t__namespace.assignmentExpression(
1282
+ "=",
1283
+ t__namespace.memberExpression(results.id, t__namespace.identifier("_$owner")),
1284
+ t__namespace.callExpression(
1285
+ registerImportMethod(path, "getOwner", getRendererConfig(path, "dom").moduleName),
1286
+ []
1287
+ )
1288
+ )
1289
+ )
1290
+ );
1259
1291
  }
1260
1292
 
1261
1293
  function createTemplate$2(path, result, wrap) {
@@ -1300,14 +1332,14 @@ function appendTemplates$1(path, templates) {
1300
1332
  template.id,
1301
1333
  t__namespace.addComment(
1302
1334
  t__namespace.callExpression(
1303
- registerImportMethod(path, "template"),
1335
+ registerImportMethod(path, "template", getRendererConfig(path, "dom").moduleName),
1304
1336
  [
1305
1337
  t__namespace.templateLiteral([t__namespace.templateElement(tmpl, true)], []),
1306
1338
  t__namespace.numericLiteral(template.elementCount)
1307
1339
  ].concat(template.isSVG ? t__namespace.booleanLiteral(template.isSVG) : [])
1308
1340
  ),
1309
- 'leading',
1310
- '#__PURE__'
1341
+ "leading",
1342
+ "#__PURE__"
1311
1343
  )
1312
1344
  );
1313
1345
  });
@@ -1331,14 +1363,18 @@ function registerTemplate(path, results) {
1331
1363
  id: templateId,
1332
1364
  template: results.template,
1333
1365
  elementCount: results.template.split("<").length - 1,
1334
- isSVG: results.isSVG
1366
+ isSVG: results.isSVG,
1367
+ renderer: "dom"
1335
1368
  });
1336
1369
  }
1337
1370
  }
1338
1371
  decl = t__namespace.variableDeclarator(
1339
1372
  results.id,
1340
1373
  hydratable
1341
- ? t__namespace.callExpression(registerImportMethod(path, "getNextElement"), templateId ? [templateId] : [])
1374
+ ? t__namespace.callExpression(
1375
+ registerImportMethod(path, "getNextElement", getRendererConfig(path, "dom").moduleName),
1376
+ templateId ? [templateId] : []
1377
+ )
1342
1378
  : t__namespace.callExpression(t__namespace.memberExpression(templateId, t__namespace.identifier("cloneNode")), [
1343
1379
  t__namespace.booleanLiteral(true)
1344
1380
  ])
@@ -1444,20 +1480,24 @@ function createTemplate$1(path, result) {
1444
1480
  }
1445
1481
 
1446
1482
  const templates =
1447
- path.scope.getProgramParent().data.templates ||
1448
- (path.scope.getProgramParent().data.templates = []);
1483
+ path.scope.getProgramParent().data.templates ||
1484
+ (path.scope.getProgramParent().data.templates = []);
1449
1485
  const found = templates.find(tmp => {
1450
- if (t__namespace.isArrayExpression(tmp[1]) && t__namespace.isArrayExpression(template)) {
1451
- return tmp[1].elements.every(
1486
+ if (t__namespace.isArrayExpression(tmp.template) && t__namespace.isArrayExpression(template)) {
1487
+ return tmp.template.elements.every(
1452
1488
  (el, i) => template.elements[i] && el.value === template.elements[i].value
1453
1489
  );
1454
1490
  }
1455
- return tmp[1].value === template.value;
1491
+ return tmp.template.value === template.value;
1456
1492
  });
1457
1493
  if (!found) {
1458
1494
  id = path.scope.generateUidIdentifier("tmpl$");
1459
- templates.push([id, template]);
1460
- } else id = found[0];
1495
+ templates.push({
1496
+ id,
1497
+ template,
1498
+ renderer: "ssr"
1499
+ });
1500
+ } else id = found.id;
1461
1501
 
1462
1502
  return t__namespace.callExpression(
1463
1503
  registerImportMethod(path, "ssr"),
@@ -1467,7 +1507,7 @@ function createTemplate$1(path, result) {
1467
1507
 
1468
1508
  function appendTemplates(path, templates) {
1469
1509
  const declarators = templates.map(template => {
1470
- return t__namespace.variableDeclarator(template[0], template[1]);
1510
+ return t__namespace.variableDeclarator(template.id, template.template);
1471
1511
  });
1472
1512
  path.node.body.unshift(t__namespace.variableDeclaration("const", declarators));
1473
1513
  }
@@ -1481,7 +1521,7 @@ function appendToTemplate(template, value) {
1481
1521
  if (array && array.length) template.push.apply(template, array);
1482
1522
  }
1483
1523
 
1484
- function transformElement$1(path, info) {
1524
+ function transformElement$2(path, info) {
1485
1525
  let tagName = getTagName(path.node),
1486
1526
  config = getConfig(path),
1487
1527
  voidTag = VoidElements.indexOf(tagName) > -1,
@@ -1491,8 +1531,10 @@ function transformElement$1(path, info) {
1491
1531
  decl: [],
1492
1532
  exprs: [],
1493
1533
  dynamics: [],
1494
- tagName
1534
+ tagName,
1535
+ renderer: "ssr"
1495
1536
  };
1537
+
1496
1538
  if (info.topLevel && config.hydratable) {
1497
1539
  results.template.push("");
1498
1540
  results.templateValues.push(
@@ -1886,7 +1928,7 @@ function transformChildren$1(path, results, { hydratable }) {
1886
1928
  });
1887
1929
  }
1888
1930
 
1889
- function transformElement(path, info) {
1931
+ function transformElement$1(path, info) {
1890
1932
  let tagName = getTagName(path.node),
1891
1933
  results = {
1892
1934
  id: path.scope.generateUidIdentifier("el$"),
@@ -1894,13 +1936,21 @@ function transformElement(path, info) {
1894
1936
  exprs: [],
1895
1937
  dynamics: [],
1896
1938
  postExprs: [],
1897
- tagName
1939
+ tagName,
1940
+ renderer: "universal"
1898
1941
  };
1899
1942
 
1900
1943
  results.decl.push(
1901
1944
  t__namespace.variableDeclarator(
1902
1945
  results.id,
1903
- t__namespace.callExpression(registerImportMethod(path, "createElement"), [t__namespace.stringLiteral(tagName)])
1946
+ t__namespace.callExpression(
1947
+ registerImportMethod(
1948
+ path,
1949
+ "createElement",
1950
+ getRendererConfig(path, "universal").moduleName
1951
+ ),
1952
+ [t__namespace.stringLiteral(tagName)]
1953
+ )
1904
1954
  )
1905
1955
  );
1906
1956
 
@@ -1924,17 +1974,24 @@ function transformAttributes(path, results) {
1924
1974
  if (t__namespace.isJSXSpreadAttribute(node)) {
1925
1975
  results.exprs.push(
1926
1976
  t__namespace.expressionStatement(
1927
- t__namespace.callExpression(registerImportMethod(attribute, "spread"), [
1928
- elem,
1929
- isDynamic(attribute.get("argument"), {
1930
- checkMember: true
1931
- })
1932
- ? t__namespace.isCallExpression(node.argument) && !node.argument.arguments.length
1933
- ? node.argument.callee
1934
- : t__namespace.arrowFunctionExpression([], node.argument)
1935
- : node.argument,
1936
- t__namespace.booleanLiteral(hasChildren)
1937
- ])
1977
+ t__namespace.callExpression(
1978
+ registerImportMethod(
1979
+ attribute,
1980
+ "spread",
1981
+ getRendererConfig(path, "universal").moduleName
1982
+ ),
1983
+ [
1984
+ elem,
1985
+ isDynamic(attribute.get("argument"), {
1986
+ checkMember: true
1987
+ })
1988
+ ? t__namespace.isCallExpression(node.argument) && !node.argument.arguments.length
1989
+ ? node.argument.callee
1990
+ : t__namespace.arrowFunctionExpression([], node.argument)
1991
+ : node.argument,
1992
+ t__namespace.booleanLiteral(hasChildren)
1993
+ ]
1994
+ )
1938
1995
  )
1939
1996
  );
1940
1997
  return;
@@ -2004,7 +2061,7 @@ function transformAttributes(path, results) {
2004
2061
  }
2005
2062
  } else if (key.startsWith("use:")) {
2006
2063
  // Some trick to treat JSXIdentifier as Identifier
2007
- node.name.name.type = 'Identifier';
2064
+ node.name.name.type = "Identifier";
2008
2065
  results.exprs.unshift(
2009
2066
  t__namespace.expressionStatement(
2010
2067
  t__namespace.callExpression(node.name.name, [
@@ -2044,7 +2101,7 @@ function transformAttributes(path, results) {
2044
2101
  function setAttr(path, elem, name, value, { prevId } = {}) {
2045
2102
  if (!value) value = t__namespace.booleanLiteral(true);
2046
2103
  return t__namespace.callExpression(
2047
- registerImportMethod(path, "setProp"),
2104
+ registerImportMethod(path, "setProp", getRendererConfig(path, "universal").moduleName),
2048
2105
  prevId ? [elem, t__namespace.stringLiteral(name), value, prevId] : [elem, t__namespace.stringLiteral(name), value]
2049
2106
  );
2050
2107
  }
@@ -2064,33 +2121,47 @@ function transformChildren(path, results) {
2064
2121
  const appends = [];
2065
2122
  childNodes.forEach((child, index) => {
2066
2123
  if (!child) return;
2124
+ if (child.tagName && child.renderer !== "universal") {
2125
+ throw new Error(`<${child.tagName}> is not supported in <${getTagName(path.node)}>.
2126
+ Wrap the usage with a component that would render this element, eg. Canvas`);
2127
+ }
2067
2128
  if (child.id) {
2068
- const insertNode = registerImportMethod(path, "insertNode");
2129
+ let insertNode = registerImportMethod(
2130
+ path,
2131
+ "insertNode",
2132
+ getRendererConfig(path, "universal").moduleName
2133
+ );
2069
2134
  let insert = child.id;
2070
2135
  if (child.text) {
2071
- const createTextNode = registerImportMethod(path, "createTextNode");
2136
+ let createTextNode = registerImportMethod(
2137
+ path,
2138
+ "createTextNode",
2139
+ getRendererConfig(path, "universal").moduleName
2140
+ );
2072
2141
  if (multi) {
2073
2142
  results.decl.push(
2074
2143
  t__namespace.variableDeclarator(
2075
2144
  child.id,
2076
2145
  t__namespace.callExpression(createTextNode, [
2077
- t__namespace.stringLiteral(htmlEntities.decode(child.template))
2146
+ t__namespace.templateLiteral([t__namespace.templateElement({ raw: child.template })], [])
2078
2147
  ])
2079
2148
  )
2080
2149
  );
2081
2150
  } else
2082
2151
  insert = t__namespace.callExpression(createTextNode, [
2083
- t__namespace.stringLiteral(htmlEntities.decode(child.template))
2152
+ t__namespace.templateLiteral([t__namespace.templateElement({ raw: child.template })], [])
2084
2153
  ]);
2085
2154
  }
2086
- appends.push(
2087
- t__namespace.expressionStatement(t__namespace.callExpression(insertNode, [results.id, insert]))
2088
- );
2155
+ appends.push(t__namespace.expressionStatement(t__namespace.callExpression(insertNode, [results.id, insert])));
2089
2156
  results.decl.push(...child.decl);
2090
2157
  results.exprs.push(...child.exprs);
2091
2158
  results.dynamics.push(...child.dynamics);
2092
2159
  } else if (child.exprs.length) {
2093
- const insert = registerImportMethod(path, "insert");
2160
+ let insert = registerImportMethod(
2161
+ path,
2162
+ "insert",
2163
+ getRendererConfig(path, "universal").moduleName
2164
+ );
2094
2165
  if (multi) {
2095
2166
  results.exprs.push(
2096
2167
  t__namespace.expressionStatement(
@@ -2103,9 +2174,7 @@ function transformChildren(path, results) {
2103
2174
  );
2104
2175
  } else {
2105
2176
  results.exprs.push(
2106
- t__namespace.expressionStatement(
2107
- t__namespace.callExpression(insert, [results.id, child.exprs[0]])
2108
- )
2177
+ t__namespace.expressionStatement(t__namespace.callExpression(insert, [results.id, child.exprs[0]]))
2109
2178
  );
2110
2179
  }
2111
2180
  }
@@ -2418,13 +2487,7 @@ function transformComponent(path) {
2418
2487
  }
2419
2488
 
2420
2489
  function transformComponentChildren(children, config) {
2421
- const createTemplate$3 =
2422
- config.generate === "universal"
2423
- ? createTemplate
2424
- : config.generate === "ssr"
2425
- ? createTemplate$1
2426
- : createTemplate$2,
2427
- filteredChildren = filterChildren(children);
2490
+ const filteredChildren = filterChildren(children);
2428
2491
  if (!filteredChildren.length) return;
2429
2492
  let dynamic = false;
2430
2493
 
@@ -2438,7 +2501,7 @@ function transformComponentChildren(children, config) {
2438
2501
  componentChild: true
2439
2502
  });
2440
2503
  dynamic = dynamic || child.dynamic;
2441
- memo.push(createTemplate$3(path, child, filteredChildren.length > 1));
2504
+ memo.push(getCreateTemplate(config, path, child)(path, child, filteredChildren.length > 1));
2442
2505
  }
2443
2506
  return memo;
2444
2507
  }, []);
@@ -2466,20 +2529,14 @@ function transformComponentChildren(children, config) {
2466
2529
  }
2467
2530
 
2468
2531
  function transformFragmentChildren(children, results, config) {
2469
- const createTemplate$3 =
2470
- config.generate === "universal"
2471
- ? createTemplate
2472
- : config.generate === "ssr"
2473
- ? createTemplate$1
2474
- : createTemplate$2,
2475
- filteredChildren = filterChildren(children),
2532
+ const filteredChildren = filterChildren(children),
2476
2533
  childNodes = filteredChildren.reduce((memo, path) => {
2477
2534
  if (t__namespace.isJSXText(path.node)) {
2478
- const v = htmlEntities.decode(trimWhitespace(path.node.extra.raw));
2535
+ const v = htmlEntities.decode(trimWhitespace(path.node.extra.raw));
2479
2536
  if (v.length) memo.push(t__namespace.stringLiteral(v));
2480
2537
  } else {
2481
2538
  const child = transformNode(path, { topLevel: true, fragmentChild: true });
2482
- memo.push(createTemplate$3(path, child, true));
2539
+ memo.push(getCreateTemplate(config, path, child)(path, child, true));
2483
2540
  }
2484
2541
  return memo;
2485
2542
  }, []);
@@ -2497,12 +2554,9 @@ function transformJSX(path) {
2497
2554
  topLevel: true
2498
2555
  }
2499
2556
  );
2500
- const template =
2501
- config.generate === "universal"
2502
- ? createTemplate
2503
- : config.generate === "ssr"
2504
- ? createTemplate$1
2505
- : createTemplate$2;
2557
+
2558
+ const template = getCreateTemplate(config, path, result);
2559
+
2506
2560
  path.replaceWith(replace(template(path, result, false)));
2507
2561
  }
2508
2562
 
@@ -2531,17 +2585,10 @@ function transformNode(path, info = {}) {
2531
2585
  const node = path.node;
2532
2586
  let staticValue;
2533
2587
  if (t__namespace.isJSXElement(node)) {
2534
- let tagName = getTagName(node);
2535
- if (isComponent(tagName)) return transformComponent(path);
2536
- const element =
2537
- config.generate === "universal"
2538
- ? transformElement
2539
- : config.generate === "ssr"
2540
- ? transformElement$1
2541
- : transformElement$2;
2542
- return element(path, info);
2588
+ return transformElement(config, path, info);
2543
2589
  } else if (t__namespace.isJSXFragment(node)) {
2544
2590
  let results = { template: "", decl: [], exprs: [], dynamics: [] };
2591
+ // <><div /><Component /></>
2545
2592
  transformFragmentChildren(path.get("children"), results, config);
2546
2593
  return results;
2547
2594
  } else if (t__namespace.isJSXText(node) || (staticValue = getStaticExpression(path))) {
@@ -2553,7 +2600,7 @@ function transformNode(path, info = {}) {
2553
2600
  : trimWhitespace(node.extra.raw);
2554
2601
  if (!text.length) return null;
2555
2602
  const results = {
2556
- template: config.generate === "dom" ? escapeBackticks(text) : text,
2603
+ template: config.generate === "ssr" ? text : escapeBackticks(text),
2557
2604
  decl: [],
2558
2605
  exprs: [],
2559
2606
  dynamics: [],
@@ -2619,21 +2666,63 @@ function transformNode(path, info = {}) {
2619
2666
  }
2620
2667
  }
2621
2668
 
2669
+ function getCreateTemplate(config, path, result) {
2670
+ if ((result.tagName && result.renderer === "dom") || config.generate === "dom") {
2671
+ return createTemplate$2;
2672
+ }
2673
+
2674
+ if (result.renderer === "ssr" || config.generate === "ssr") {
2675
+ return createTemplate$1;
2676
+ }
2677
+
2678
+ return createTemplate;
2679
+ }
2680
+
2681
+ function transformElement(config, path, info = {}) {
2682
+ const node = path.node;
2683
+ let tagName = getTagName(node);
2684
+ // <Component ...></Component>
2685
+ if (isComponent(tagName)) return transformComponent(path);
2686
+
2687
+ // <div ...></div>
2688
+ // const element = getTransformElemet(config, path, tagName);
2689
+
2690
+ let tagRenderer;
2691
+ for (var renderer of config.renderers ?? []) {
2692
+ if (renderer.elements.indexOf(tagName) !== -1) {
2693
+ tagRenderer = renderer;
2694
+ break;
2695
+ }
2696
+ }
2697
+
2698
+ if (tagRenderer?.name === "dom" || getConfig(path).generate === "dom") {
2699
+ return transformElement$3(path, info);
2700
+ }
2701
+
2702
+ if (getConfig(path).generate === "ssr") {
2703
+ return transformElement$2(path, info);
2704
+ }
2705
+
2706
+ return transformElement$1(path);
2707
+ }
2708
+
2622
2709
  // add to the top/bottom of the module.
2623
2710
  var postprocess = path => {
2624
- const config = getConfig(path);
2625
2711
  if (path.scope.data.events) {
2626
2712
  path.node.body.push(
2627
2713
  t__namespace.expressionStatement(
2628
- t__namespace.callExpression(registerImportMethod(path, "delegateEvents"), [
2629
- t__namespace.arrayExpression(Array.from(path.scope.data.events).map(e => t__namespace.stringLiteral(e)))
2630
- ])
2714
+ t__namespace.callExpression(
2715
+ registerImportMethod(path, "delegateEvents", getRendererConfig(path, "dom").moduleName),
2716
+ [t__namespace.arrayExpression(Array.from(path.scope.data.events).map(e => t__namespace.stringLiteral(e)))]
2717
+ )
2631
2718
  )
2632
2719
  );
2633
2720
  }
2634
- if (path.scope.data.templates) {
2635
- const appendTemplates$2 = config.generate === "ssr" ? appendTemplates : appendTemplates$1;
2636
- appendTemplates$2(path, path.scope.data.templates);
2721
+ if (path.scope.data.templates?.length) {
2722
+ let domTemplates = path.scope.data.templates.filter(temp => temp.renderer === "dom");
2723
+ let ssrTemplates = path.scope.data.templates.filter(temp => temp.renderer === "ssr");
2724
+ domTemplates.length > 0 && appendTemplates$1(path, domTemplates);
2725
+ ssrTemplates.length > 0 && appendTemplates(path, ssrTemplates);
2637
2726
  }
2638
2727
  };
2639
2728