marko 5.37.7 → 5.37.8

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.
@@ -160,27 +160,29 @@ exports.p = function (domCompat) {
160
160
  const componentsContext = T_(out);
161
161
  const globalComponentsContext = componentsContext.q_;
162
162
  let customEvents;
163
+ let normalizedInput;
163
164
  globalComponentsContext.aA_ = existingComponent;
164
165
  out.sync();
165
166
  if (renderer) {
166
167
  const [rawInput] = input;
167
- const normalizedInput = {};
168
+ normalizedInput = {};
168
169
 
169
170
  for (const key in rawInput) {
170
- let value = rawInput[key];
171
- if (key.startsWith("on")) {
172
- const c = key[2];
173
- customEvents = customEvents || {};
174
- customEvents[(c === "-" ? "" : c.toLowerCase()) + key.slice(3)] = [
175
- value];
176
-
171
+ const value = rawInput[key];
172
+ if (/^on[-A-Z]/.test(key)) {
173
+ if (typeof value === "function") {
174
+ (customEvents || (customEvents = {}))[
175
+ key[2] === "-" ? key.slice(3) : key.slice(2).toLowerCase()] =
176
+ [value];
177
+ }
177
178
  } else {
178
- normalizedInput[key] = rawInput[key];
179
+ normalizedInput[key === "content" ? "renderBody" : key] = value;
179
180
  }
180
181
  }
181
182
 
182
183
  renderer(normalizedInput, out);
183
184
  } else {
185
+ normalizedInput = input[0];
184
186
  RenderBodyComponent({ renderBody, args: input }, out);
185
187
  }
186
188
 
@@ -192,7 +194,7 @@ exports.p = function (domCompat) {
192
194
  );
193
195
  const component = componentDefs[0].t_;
194
196
  component._F_ = rootNode;
195
- component.P_ = input[0];
197
+ component.P_ = normalizedInput;
196
198
  component.X_ = customEvents;
197
199
  scope.bq_ = component;
198
200
  });
@@ -83,17 +83,17 @@ exports.p = function (htmlCompat) {
83
83
  const normalizedInput = {};
84
84
 
85
85
  for (const key in input) {
86
- let value = input[key];
87
- if (key.startsWith("on") && typeof value === "function") {
88
- const c = key[2];
89
- customEvents = customEvents || [];
90
- customEvents.push([
91
- (c === "-" ? "" : c.toLowerCase()) + key.slice(3),
92
- value]
93
- );
94
- value.toJSON = htmlCompat.toJSON;
86
+ const value = input[key];
87
+ if (/^on[-A-Z]/.test(key)) {
88
+ if (typeof value === "function") {
89
+ (customEvents || (customEvents = [])).push([
90
+ key[2] === "-" ? key.slice(3) : key.slice(2).toLowerCase(),
91
+ value]
92
+ );
93
+ value.toJSON = htmlCompat.toJSON;
94
+ }
95
95
  } else {
96
- normalizedInput[key] = input[key];
96
+ normalizedInput[key === "content" ? "renderBody" : key] = value;
97
97
  }
98
98
  }
99
99
  renderer5(normalizedInput, out);
@@ -1,4 +1,4 @@
1
- "use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule = true;exports.analyze = void 0;exports.getRuntimeEntryFiles = getRuntimeEntryFiles;exports.translate = exports.taglibs = exports.preferAPI = exports.optionalTaglibs = exports.internalEntryBuilder = void 0;var _compiler = require("@marko/compiler");
1
+ "use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule = true;exports.analyze = void 0;exports.getRuntimeEntryFiles = getRuntimeEntryFiles;exports.translate = exports.taglibs = exports.tagDiscoveryDirs = exports.preferAPI = exports.optionalTaglibs = exports.internalEntryBuilder = void 0;var _compiler = require("@marko/compiler");
2
2
  var _babelUtils = require("@marko/compiler/babel-utils");
3
3
 
4
4
 
@@ -31,7 +31,8 @@ var _getComponentFiles = _interopRequireDefault(require("./util/get-component-fi
31
31
  var _optimizeHtmlWrites = require("./util/optimize-html-writes");
32
32
  var _optimizeVdomCreate = require("./util/optimize-vdom-create");
33
33
 
34
- var _taglib = _interopRequireWildcard(require("./taglib"));exports.optionalTaglibs = _taglib.optionalTaglibs;exports.taglibs = _taglib.default;function _getRequireWildcardCache(e) {if ("function" != typeof WeakMap) return null;var r = new WeakMap(),t = new WeakMap();return (_getRequireWildcardCache = function (e) {return e ? t : r;})(e);}function _interopRequireWildcard(e, r) {if (!r && e && e.__esModule) return e;if (null === e || "object" != typeof e && "function" != typeof e) return { default: e };var t = _getRequireWildcardCache(r);if (t && t.has(e)) return t.get(e);var n = { __proto__: null },a = Object.defineProperty && Object.getOwnPropertyDescriptor;for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) {var i = a ? Object.getOwnPropertyDescriptor(e, u) : null;i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u];}return n.default = e, t && t.set(e, n), n;}
34
+
35
+ var _taglib = _interopRequireWildcard(require("./taglib"));exports.optionalTaglibs = _taglib.optionalTaglibs;exports.taglibs = _taglib.default;function _getRequireWildcardCache(e) {if ("function" != typeof WeakMap) return null;var r = new WeakMap(),t = new WeakMap();return (_getRequireWildcardCache = function (e) {return e ? t : r;})(e);}function _interopRequireWildcard(e, r) {if (!r && e && e.__esModule) return e;if (null === e || "object" != typeof e && "function" != typeof e) return { default: e };var t = _getRequireWildcardCache(r);if (t && t.has(e)) return t.get(e);var n = { __proto__: null },a = Object.defineProperty && Object.getOwnPropertyDescriptor;for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) {var i = a ? Object.getOwnPropertyDescriptor(e, u) : null;i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u];}return n.default = e, t && t.set(e, n), n;}const tagDiscoveryDirs = exports.tagDiscoveryDirs = ["components"];
35
36
 
36
37
 
37
38
  const preferAPI = exports.preferAPI = "class";
@@ -92,6 +93,7 @@ const analyze = exports.analyze = {
92
93
  const tagDef = (0, _babelUtils.getTagDef)(tag);
93
94
  // Check if tag uses stateful tag params.
94
95
  const meta = tag.hub.file.metadata.marko;
96
+ let relativePath;
95
97
 
96
98
  if (tagDef) {
97
99
  if (tagDef.html && !tagDef.template && !tagDef.renderer) {
@@ -106,17 +108,8 @@ const analyze = exports.analyze = {
106
108
  );
107
109
  }
108
110
  }
109
- } else if (tag.get("name").isStringLiteral()) {
110
- const relativePath = resolveRelativeTagEntry(file, tagDef);
111
-
112
- if (relativePath) {
113
- tag.node.extra = tag.node.extra || {};
114
- tag.node.extra.relativePath = relativePath;
115
-
116
- if (!meta.tags.includes(relativePath)) {
117
- meta.tags.push(relativePath);
118
- }
119
- }
111
+ } else if (_compiler.types.isStringLiteral(tag.node.name)) {
112
+ relativePath = resolveRelativeTagEntry(file, tagDef);
120
113
  }
121
114
 
122
115
  if (tagDef.translator && tagDef.translator.path) {
@@ -126,6 +119,33 @@ const analyze = exports.analyze = {
126
119
  }
127
120
  }
128
121
 
122
+ if (!relativePath && _compiler.types.isStringLiteral(tag.node.name)) {
123
+ const tagName = tag.node.name.value;
124
+ const binding =
125
+ /^[A-Z][a-zA-Z0-9_$]*$/.test(tagName) && tag.scope.getBinding(tagName);
126
+ if (binding && binding.kind === "module" && binding.identifier.loc) {
127
+ const importSource = binding.path.parent.source.value;
128
+ relativePath = (0, _babelUtils.resolveTagImport)(tag, importSource) || importSource;
129
+ tag.node.extra = tag.node.extra || {};
130
+ tag.node.extra.tagNameImported = relativePath;
131
+ }
132
+ }
133
+
134
+ if (relativePath) {
135
+ tag.node.extra = tag.node.extra || {};
136
+ tag.node.extra.relativePath = relativePath;
137
+
138
+ if (!meta.tags.includes(relativePath)) {
139
+ meta.tags.push(relativePath);
140
+ }
141
+
142
+ const childFile = (0, _babelUtils.loadFileForTag)(tag);
143
+ if (childFile?.ast.program.extra?.featureType === "tags") {
144
+ tag.node.extra.featureType = "tags";
145
+ (file.path.node.extra ??= {}).needsCompat = true;
146
+ }
147
+ }
148
+
129
149
  if (!(meta.hasFunctionEventHandlers || meta.hasStringEventHandlers)) {
130
150
  for (const attr of tag.node.attributes) {
131
151
  if (
@@ -311,6 +331,15 @@ const translate = exports.translate = {
311
331
  path.unshiftContainer(
312
332
  "body",
313
333
  [
334
+ path.node.extra?.needsCompat &&
335
+ _compiler.types.importDeclaration(
336
+ [],
337
+ _compiler.types.stringLiteral(
338
+ `marko/${markoOpts.optimize ? "dist" : "src"}/runtime/helpers/tags-compat/${
339
+ markoOpts.output === "html" ? "html" : "dom"}${
340
+ markoOpts.optimize ? "" : "-debug"}.${markoOpts.modules === "esm" ? "mjs" : "js"}`
341
+ )
342
+ ),
314
343
  _compiler.types.importDeclaration(
315
344
  [_compiler.types.importSpecifier(runtimeTemplateIdentifier, _compiler.types.identifier("t"))],
316
345
  _compiler.types.stringLiteral(
@@ -25,6 +25,16 @@ function _default(path, isNullable) {
25
25
 
26
26
  let tagIdentifier;
27
27
 
28
+ if (node.extra?.featureType === "tags") {
29
+ path.set(
30
+ "name",
31
+ path.scope.hasBinding(name.value) ?
32
+ _compiler.types.identifier(name.value) :
33
+ (0, _babelUtils.importDefault)(file, node.extra.relativePath, name.value)
34
+ );
35
+ return (0, _dynamicTag.default)(path);
36
+ }
37
+
28
38
  if (_compiler.types.isStringLiteral(name)) {
29
39
  const tagName = name.value;
30
40
  let relativePath = node.extra && node.extra.relativePath;
@@ -42,41 +52,13 @@ function _default(path, isNullable) {
42
52
  let binding = !relativePath && path.scope.getBinding(tagName);
43
53
  if (binding && !binding.identifier.loc) binding = null;
44
54
 
45
- if (binding && binding.kind === "module") {
46
- const importSource = binding.path.parent.source;
47
- relativePath =
48
- (0, _babelUtils.resolveTagImport)(path, importSource.value) || importSource.value;
49
- (node.extra ??= {}).tagNameImported = relativePath;
50
- binding = undefined;
51
- }
52
-
53
- const childFile = (0, _babelUtils.loadFileForTag)(path);
54
- const childProgram = childFile?.ast.program;
55
-
56
- if (childProgram?.extra?.featureType === "tags") {
57
- const compatRuntimeFile = `marko/src/runtime/helpers/tags-compat/${
58
- markoOpts.output === "html" ? "html" : "dom"}${
59
- markoOpts.optimize ? "" : "-debug"}.${markoOpts.modules === "esm" ? "mjs" : "js"}`;
60
- (0, _babelUtils.importDefault)(file, compatRuntimeFile);
61
- path.set("name", (0, _babelUtils.importDefault)(file, relativePath, path.node.name.value));
55
+ if (relativePath) {
56
+ tagIdentifier = (0, _babelUtils.importDefault)(file, relativePath, tagName);
57
+ } else if (binding) {
58
+ path.set("name", _compiler.types.identifier(tagName));
62
59
  return (0, _dynamicTag.default)(path);
63
- } else if (relativePath) {
64
- if (binding) {
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
- // TODO: implement auto migration for conflicts here
73
- // and log below warning
74
- // console.warn(
75
- // path.buildCodeFrameError(
76
- // `The <${tagName}> tag has been resolved from the filesystem, however a local variable with the same name exists. In the next major version of Marko the local variable will tag precedence.`
77
- // )
78
- // );
79
- }tagIdentifier = (0, _babelUtils.importDefault)(file, relativePath, tagName);} else if (binding) {path.set("name", _compiler.types.identifier(tagName));return (0, _dynamicTag.default)(path);} else if (markoOpts.ignoreUnrecognizedTags) {return (0, _nativeTag.default)(path);
60
+ } else if (markoOpts.ignoreUnrecognizedTags) {
61
+ return (0, _nativeTag.default)(path);
80
62
  } else {
81
63
  throw path.
82
64
  get("name").
@@ -9,7 +9,8 @@ function _default(path) {
9
9
  node,
10
10
  hub: { file }
11
11
  } = path;
12
- const tagProperties = path.node.extra && path.node.extra.properties || [];
12
+ const extra = path.node.extra || {};
13
+ const tagProperties = extra.properties || [];
13
14
  const { key, arguments: args } = node;
14
15
  const foundAttrs = (0, _util.getAttrs)(path, true);
15
16
  let renderBodyProp;
@@ -34,8 +35,10 @@ function _default(path) {
34
35
  }
35
36
 
36
37
  if (_compiler.types.isObjectExpression(foundAttrs)) {
38
+ const renderBodyKey =
39
+ extra.featureType === "tags" ? "content" : "renderBody";
37
40
  const renderBodyIndex = foundAttrs.properties.findIndex(
38
- (prop) => prop.key && prop.key.value === "renderBody"
41
+ (prop) => prop.key && prop.key.value === renderBodyKey
39
42
  );
40
43
 
41
44
  attrsLen = foundAttrs.properties.length;
@@ -4,6 +4,8 @@ var _babelUtils = require("@marko/compiler/babel-utils");
4
4
 
5
5
 
6
6
 
7
+
8
+
7
9
  var _classValue = _interopRequireDefault(require("marko/src/runtime/helpers/class-value"));
8
10
  var _styleValue = _interopRequireDefault(require("marko/src/runtime/helpers/style-value"));
9
11
 
@@ -22,6 +24,8 @@ function getAttrs(path, preserveNames, isAttrTag) {
22
24
  const tagDef = (0, _babelUtils.getTagDef)(path);
23
25
  const foundProperties = {};
24
26
  const hasAttributeTags = !!attributeTags.length;
27
+ const isTagsAPI = findRootTag(path)?.node.extra?.featureType === "tags";
28
+ const renderBodyKey = isTagsAPI ? "content" : "renderBody";
25
29
 
26
30
  for (let i = 0; i < attrsLen; i++) {
27
31
  const { name, value } = attributes[i];
@@ -78,7 +82,7 @@ function getAttrs(path, preserveNames, isAttrTag) {
78
82
  if (childLen && !hasAttributeTags) {
79
83
  properties.push(
80
84
  _compiler.types.objectProperty(
81
- _compiler.types.stringLiteral("renderBody"),
85
+ _compiler.types.stringLiteral(renderBodyKey),
82
86
  _compiler.types.arrowFunctionExpression(
83
87
  [_compiler.types.identifier("out"), ...params],
84
88
  _compiler.types.blockStatement(body)
@@ -243,4 +247,14 @@ function mergeSpread(properties, value) {
243
247
  } else {
244
248
  properties.push(_compiler.types.spreadElement(value));
245
249
  }
250
+ }
251
+
252
+ function findRootTag(tag) {
253
+ let cur = tag;
254
+
255
+ while ((0, _babelUtils.isAttributeTag)(cur)) {
256
+ cur = (0, _babelUtils.findParentTag)(cur);
257
+ }
258
+
259
+ return cur;
246
260
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "5.37.7",
3
+ "version": "5.37.8",
4
4
  "description": "UI Components + streaming, async, high performance, HTML templating for Node.js and the browser.",
5
5
  "keywords": [
6
6
  "front-end",
@@ -70,7 +70,7 @@
70
70
  },
71
71
  "dependencies": {
72
72
  "@babel/runtime": "^7.26.0",
73
- "@marko/compiler": "^5.39.6",
73
+ "@marko/compiler": "^5.39.7",
74
74
  "app-module-path": "^2.2.0",
75
75
  "argly": "^1.2.0",
76
76
  "browser-refresh-client": "1.1.4",
@@ -160,27 +160,29 @@ exports.p = function (domCompat) {
160
160
  const componentsContext = ___getComponentsContext(out);
161
161
  const globalComponentsContext = componentsContext.___globalContext;
162
162
  let customEvents;
163
+ let normalizedInput;
163
164
  globalComponentsContext.___rerenderComponent = existingComponent;
164
165
  out.sync();
165
166
  if (renderer) {
166
167
  const [rawInput] = input;
167
- const normalizedInput = {};
168
+ normalizedInput = {};
168
169
 
169
170
  for (const key in rawInput) {
170
- let value = rawInput[key];
171
- if (key.startsWith("on")) {
172
- const c = key[2];
173
- customEvents = customEvents || {};
174
- customEvents[(c === "-" ? "" : c.toLowerCase()) + key.slice(3)] = [
175
- value,
176
- ];
171
+ const value = rawInput[key];
172
+ if (/^on[-A-Z]/.test(key)) {
173
+ if (typeof value === "function") {
174
+ (customEvents || (customEvents = {}))[
175
+ key[2] === "-" ? key.slice(3) : key.slice(2).toLowerCase()
176
+ ] = [value];
177
+ }
177
178
  } else {
178
- normalizedInput[key] = rawInput[key];
179
+ normalizedInput[key === "content" ? "renderBody" : key] = value;
179
180
  }
180
181
  }
181
182
 
182
183
  renderer(normalizedInput, out);
183
184
  } else {
185
+ normalizedInput = input[0];
184
186
  RenderBodyComponent({ renderBody, args: input }, out);
185
187
  }
186
188
 
@@ -192,7 +194,7 @@ exports.p = function (domCompat) {
192
194
  );
193
195
  const component = componentDefs[0].___component;
194
196
  component.___rootNode = rootNode;
195
- component.___input = input[0];
197
+ component.___input = normalizedInput;
196
198
  component.___customEvents = customEvents;
197
199
  scope.___marko5Component = component;
198
200
  });
@@ -83,17 +83,17 @@ exports.p = function (htmlCompat) {
83
83
  const normalizedInput = {};
84
84
 
85
85
  for (const key in input) {
86
- let value = input[key];
87
- if (key.startsWith("on") && typeof value === "function") {
88
- const c = key[2];
89
- customEvents = customEvents || [];
90
- customEvents.push([
91
- (c === "-" ? "" : c.toLowerCase()) + key.slice(3),
92
- value,
93
- ]);
94
- value.toJSON = htmlCompat.toJSON;
86
+ const value = input[key];
87
+ if (/^on[-A-Z]/.test(key)) {
88
+ if (typeof value === "function") {
89
+ (customEvents || (customEvents = [])).push([
90
+ key[2] === "-" ? key.slice(3) : key.slice(2).toLowerCase(),
91
+ value,
92
+ ]);
93
+ value.toJSON = htmlCompat.toJSON;
94
+ }
95
95
  } else {
96
- normalizedInput[key] = input[key];
96
+ normalizedInput[key === "content" ? "renderBody" : key] = value;
97
97
  }
98
98
  }
99
99
  renderer5(normalizedInput, out);
@@ -31,6 +31,7 @@ import getComponentFiles from "./util/get-component-files";
31
31
  import { optimizeHTMLWrites } from "./util/optimize-html-writes";
32
32
  import { analyzeStaticVDOM } from "./util/optimize-vdom-create";
33
33
 
34
+ export const tagDiscoveryDirs = ["components"];
34
35
  export { optionalTaglibs, default as taglibs } from "./taglib";
35
36
  export { entryBuilder as internalEntryBuilder } from "./util/add-dependencies";
36
37
 
@@ -92,6 +93,7 @@ export const analyze = {
92
93
  const tagDef = getTagDef(tag);
93
94
  // Check if tag uses stateful tag params.
94
95
  const meta = tag.hub.file.metadata.marko;
96
+ let relativePath;
95
97
 
96
98
  if (tagDef) {
97
99
  if (tagDef.html && !tagDef.template && !tagDef.renderer) {
@@ -106,17 +108,8 @@ export const analyze = {
106
108
  );
107
109
  }
108
110
  }
109
- } else if (tag.get("name").isStringLiteral()) {
110
- const relativePath = resolveRelativeTagEntry(file, tagDef);
111
-
112
- if (relativePath) {
113
- tag.node.extra = tag.node.extra || {};
114
- tag.node.extra.relativePath = relativePath;
115
-
116
- if (!meta.tags.includes(relativePath)) {
117
- meta.tags.push(relativePath);
118
- }
119
- }
111
+ } else if (t.isStringLiteral(tag.node.name)) {
112
+ relativePath = resolveRelativeTagEntry(file, tagDef);
120
113
  }
121
114
 
122
115
  if (tagDef.translator && tagDef.translator.path) {
@@ -126,6 +119,33 @@ export const analyze = {
126
119
  }
127
120
  }
128
121
 
122
+ if (!relativePath && t.isStringLiteral(tag.node.name)) {
123
+ const tagName = tag.node.name.value;
124
+ const binding =
125
+ /^[A-Z][a-zA-Z0-9_$]*$/.test(tagName) && tag.scope.getBinding(tagName);
126
+ if (binding && binding.kind === "module" && binding.identifier.loc) {
127
+ const importSource = binding.path.parent.source.value;
128
+ relativePath = resolveTagImport(tag, importSource) || importSource;
129
+ tag.node.extra = tag.node.extra || {};
130
+ tag.node.extra.tagNameImported = relativePath;
131
+ }
132
+ }
133
+
134
+ if (relativePath) {
135
+ tag.node.extra = tag.node.extra || {};
136
+ tag.node.extra.relativePath = relativePath;
137
+
138
+ if (!meta.tags.includes(relativePath)) {
139
+ meta.tags.push(relativePath);
140
+ }
141
+
142
+ const childFile = loadFileForTag(tag);
143
+ if (childFile?.ast.program.extra?.featureType === "tags") {
144
+ tag.node.extra.featureType = "tags";
145
+ (file.path.node.extra ??= {}).needsCompat = true;
146
+ }
147
+ }
148
+
129
149
  if (!(meta.hasFunctionEventHandlers || meta.hasStringEventHandlers)) {
130
150
  for (const attr of tag.node.attributes) {
131
151
  if (
@@ -311,6 +331,15 @@ export const translate = {
311
331
  path.unshiftContainer(
312
332
  "body",
313
333
  [
334
+ path.node.extra?.needsCompat &&
335
+ t.importDeclaration(
336
+ [],
337
+ t.stringLiteral(
338
+ `marko/${markoOpts.optimize ? "dist" : "src"}/runtime/helpers/tags-compat/${
339
+ markoOpts.output === "html" ? "html" : "dom"
340
+ }${markoOpts.optimize ? "" : "-debug"}.${markoOpts.modules === "esm" ? "mjs" : "js"}`,
341
+ ),
342
+ ),
314
343
  t.importDeclaration(
315
344
  [t.importSpecifier(runtimeTemplateIdentifier, t.identifier("t"))],
316
345
  t.stringLiteral(
@@ -25,6 +25,16 @@ export default function (path, isNullable) {
25
25
 
26
26
  let tagIdentifier;
27
27
 
28
+ if (node.extra?.featureType === "tags") {
29
+ path.set(
30
+ "name",
31
+ path.scope.hasBinding(name.value)
32
+ ? t.identifier(name.value)
33
+ : importDefault(file, node.extra.relativePath, name.value),
34
+ );
35
+ return dynamicTag(path);
36
+ }
37
+
28
38
  if (t.isStringLiteral(name)) {
29
39
  const tagName = name.value;
30
40
  let relativePath = node.extra && node.extra.relativePath;
@@ -42,35 +52,7 @@ export default function (path, isNullable) {
42
52
  let binding = !relativePath && path.scope.getBinding(tagName);
43
53
  if (binding && !binding.identifier.loc) binding = null;
44
54
 
45
- if (binding && binding.kind === "module") {
46
- const importSource = binding.path.parent.source;
47
- relativePath =
48
- resolveTagImport(path, importSource.value) || importSource.value;
49
- (node.extra ??= {}).tagNameImported = relativePath;
50
- binding = undefined;
51
- }
52
-
53
- const childFile = loadFileForTag(path);
54
- const childProgram = childFile?.ast.program;
55
-
56
- if (childProgram?.extra?.featureType === "tags") {
57
- const compatRuntimeFile = `marko/src/runtime/helpers/tags-compat/${
58
- markoOpts.output === "html" ? "html" : "dom"
59
- }${markoOpts.optimize ? "" : "-debug"}.${markoOpts.modules === "esm" ? "mjs" : "js"}`;
60
- importDefault(file, compatRuntimeFile);
61
- path.set("name", importDefault(file, relativePath, path.node.name.value));
62
- return dynamicTag(path);
63
- } else if (relativePath) {
64
- if (binding) {
65
- // TODO: implement auto migration for conflicts here
66
- // and log below warning
67
- // console.warn(
68
- // path.buildCodeFrameError(
69
- // `The <${tagName}> tag has been resolved from the filesystem, however a local variable with the same name exists. In the next major version of Marko the local variable will tag precedence.`
70
- // )
71
- // );
72
- }
73
-
55
+ if (relativePath) {
74
56
  tagIdentifier = importDefault(file, relativePath, tagName);
75
57
  } else if (binding) {
76
58
  path.set("name", t.identifier(tagName));
@@ -9,7 +9,8 @@ export default function (path) {
9
9
  node,
10
10
  hub: { file },
11
11
  } = path;
12
- const tagProperties = (path.node.extra && path.node.extra.properties) || [];
12
+ const extra = path.node.extra || {};
13
+ const tagProperties = extra.properties || [];
13
14
  const { key, arguments: args } = node;
14
15
  const foundAttrs = getAttrs(path, true);
15
16
  let renderBodyProp;
@@ -34,8 +35,10 @@ export default function (path) {
34
35
  }
35
36
 
36
37
  if (t.isObjectExpression(foundAttrs)) {
38
+ const renderBodyKey =
39
+ extra.featureType === "tags" ? "content" : "renderBody";
37
40
  const renderBodyIndex = foundAttrs.properties.findIndex(
38
- (prop) => prop.key && prop.key.value === "renderBody",
41
+ (prop) => prop.key && prop.key.value === renderBodyKey,
39
42
  );
40
43
 
41
44
  attrsLen = foundAttrs.properties.length;
@@ -1,8 +1,10 @@
1
1
  import { types as t } from "@marko/compiler";
2
2
  import {
3
3
  computeNode,
4
+ findParentTag,
4
5
  getTagDef,
5
6
  importNamed,
7
+ isAttributeTag,
6
8
  } from "@marko/compiler/babel-utils";
7
9
  import classToString from "marko/src/runtime/helpers/class-value";
8
10
  import styleToString from "marko/src/runtime/helpers/style-value";
@@ -22,6 +24,8 @@ export function getAttrs(path, preserveNames, isAttrTag) {
22
24
  const tagDef = getTagDef(path);
23
25
  const foundProperties = {};
24
26
  const hasAttributeTags = !!attributeTags.length;
27
+ const isTagsAPI = findRootTag(path)?.node.extra?.featureType === "tags";
28
+ const renderBodyKey = isTagsAPI ? "content" : "renderBody";
25
29
 
26
30
  for (let i = 0; i < attrsLen; i++) {
27
31
  const { name, value } = attributes[i];
@@ -78,7 +82,7 @@ export function getAttrs(path, preserveNames, isAttrTag) {
78
82
  if (childLen && !hasAttributeTags) {
79
83
  properties.push(
80
84
  t.objectProperty(
81
- t.stringLiteral("renderBody"),
85
+ t.stringLiteral(renderBodyKey),
82
86
  t.arrowFunctionExpression(
83
87
  [t.identifier("out"), ...params],
84
88
  t.blockStatement(body),
@@ -244,3 +248,13 @@ function mergeSpread(properties, value) {
244
248
  properties.push(t.spreadElement(value));
245
249
  }
246
250
  }
251
+
252
+ function findRootTag(tag) {
253
+ let cur = tag;
254
+
255
+ while (isAttributeTag(cur)) {
256
+ cur = findParentTag(cur);
257
+ }
258
+
259
+ return cur;
260
+ }