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