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.
- package/dist/runtime/helpers/tags-compat/runtime-dom.js +12 -10
- package/dist/runtime/helpers/tags-compat/runtime-html.js +10 -10
- package/dist/translator/index.js +42 -13
- package/dist/translator/tag/custom-tag.js +16 -34
- package/dist/translator/tag/dynamic-tag.js +5 -2
- package/dist/translator/tag/util.js +15 -1
- package/package.json +2 -2
- package/src/runtime/helpers/tags-compat/runtime-dom.js +12 -10
- package/src/runtime/helpers/tags-compat/runtime-html.js +10 -10
- package/src/translator/index.js +40 -11
- package/src/translator/tag/custom-tag.js +11 -29
- package/src/translator/tag/dynamic-tag.js +5 -2
- package/src/translator/tag/util.js +15 -1
|
@@ -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
|
-
|
|
168
|
+
normalizedInput = {};
|
|
168
169
|
|
|
169
170
|
for (const key in rawInput) {
|
|
170
|
-
|
|
171
|
-
if (key
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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] =
|
|
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_ =
|
|
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
|
-
|
|
87
|
-
if (key
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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] =
|
|
96
|
+
normalizedInput[key === "content" ? "renderBody" : key] = value;
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
renderer5(normalizedInput, out);
|
package/dist/translator/index.js
CHANGED
|
@@ -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
|
-
|
|
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 (
|
|
110
|
-
|
|
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 (
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
(
|
|
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 (
|
|
64
|
-
|
|
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
|
|
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 ===
|
|
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(
|
|
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.
|
|
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.
|
|
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
|
-
|
|
168
|
+
normalizedInput = {};
|
|
168
169
|
|
|
169
170
|
for (const key in rawInput) {
|
|
170
|
-
|
|
171
|
-
if (key
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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] =
|
|
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 =
|
|
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
|
-
|
|
87
|
-
if (key
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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] =
|
|
96
|
+
normalizedInput[key === "content" ? "renderBody" : key] = value;
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
renderer5(normalizedInput, out);
|
package/src/translator/index.js
CHANGED
|
@@ -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.
|
|
110
|
-
|
|
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 (
|
|
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
|
|
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 ===
|
|
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(
|
|
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
|
+
}
|