@marko/translator-default 5.25.6 → 5.25.8-next.0

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -461,7 +461,7 @@ function getRuntimeEntryFiles(output, optimize) {
461
461
  `${base}runtime/components/index.js`,
462
462
  `${base}runtime/components/defineComponent.js`,
463
463
  `${base}runtime/components/renderer.js`,
464
- `${base}runtime/components/registry`,
464
+ `${base}runtime/components/registry.js`,
465
465
  `${base}runtime/components/attach-detach.js`,
466
466
  `${base}runtime/helpers/assign.js`,
467
467
  `${base}runtime/helpers/class-value.js`,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@marko/translator-default",
3
3
  "description": "Translates Marko templates to the default Marko runtime.",
4
- "version": "5.25.6",
4
+ "version": "5.25.8-next.0",
5
5
  "author": "Dylan Piercey <dpiercey@ebay.com>",
6
6
  "bugs": "https://github.com/marko-js/marko/issues/new?template=Bug_report.md",
7
7
  "dependencies": {
@@ -12,8 +12,8 @@
12
12
  "self-closing-tags": "^1.0.1"
13
13
  },
14
14
  "devDependencies": {
15
- "@marko/compiler": "^5.27.6",
16
- "marko": "^5.25.5"
15
+ "@marko/compiler": "^5.27.8-next.0",
16
+ "marko": "^5.25.12-next.0"
17
17
  },
18
18
  "files": [
19
19
  "dist",
@@ -30,12 +30,12 @@
30
30
  "plugin"
31
31
  ],
32
32
  "license": "MIT",
33
- "main": "dist/index.js",
33
+ "main": "src/index.js",
34
34
  "main:dev": "src/index.js",
35
35
  "main:npm": "dist/index.js",
36
36
  "peerDependencies": {
37
- "@marko/compiler": "^5.16.1",
38
- "marko": "^5.17.2"
37
+ "@marko/compiler": "^5.27.8-next.0",
38
+ "marko": "^5.25.12-next.0"
39
39
  },
40
40
  "publishConfig": {
41
41
  "access": "public"
package/src/index.js ADDED
@@ -0,0 +1,519 @@
1
+ import { resolve } from "path";
2
+ import { types as t } from "@marko/compiler";
3
+ import {
4
+ parseExpression,
5
+ resolveTagImport,
6
+ resolveRelativePath,
7
+ importNamed,
8
+ importDefault,
9
+ parseScript,
10
+ isNativeTag,
11
+ isMacroTag,
12
+ isDynamicTag,
13
+ isAttributeTag,
14
+ loadFileForTag,
15
+ findParentTag,
16
+ getTagDef
17
+ } from "@marko/babel-utils";
18
+ import { version } from "marko/package.json";
19
+ import MarkoDocumentType from "./document-type";
20
+ import MarkoDeclaration from "./declaration";
21
+ import MarkoCDATA from "./cdata";
22
+ import MarkoTag from "./tag";
23
+ import MarkoText from "./text";
24
+ import MarkoPlaceholder from "./placeholder";
25
+ import MarkoComment from "./comment";
26
+ import MarkoScriptlet from "./scriptlet";
27
+ import MarkoClass from "./class";
28
+ import { analyzeStaticVDOM } from "./util/optimize-vdom-create";
29
+ import { optimizeHTMLWrites } from "./util/optimize-html-writes";
30
+ import getComponentFiles from "./util/get-component-files";
31
+ import addDependencies from "./util/add-dependencies";
32
+
33
+ export { default as taglibs } from "./taglib";
34
+
35
+ export const analyze = {
36
+ Program: {
37
+ enter(program) {
38
+ // Pre populate metadata for component files.
39
+ const meta = program.hub.file.metadata.marko;
40
+ getComponentFiles(program);
41
+
42
+ if (!meta.hasComponent && !meta.hasComponentBrowser) {
43
+ meta.hasComponent = program
44
+ .get("body")
45
+ .some(child => child.isMarkoClass());
46
+ }
47
+ },
48
+ exit(program) {
49
+ const { file } = program.hub;
50
+ const meta = file.metadata.marko;
51
+ const { styleFile, packageFile, componentBrowserFile } =
52
+ getComponentFiles(program);
53
+
54
+ if (packageFile) {
55
+ meta.deps.unshift(`package: ${packageFile}`);
56
+ }
57
+
58
+ if (styleFile) {
59
+ meta.deps.unshift(styleFile);
60
+ }
61
+
62
+ if (meta.hasComponentBrowser) {
63
+ meta.component = componentBrowserFile;
64
+ } else if (meta.hasComponent || meta.hasStatefulTagParams) {
65
+ meta.component = file.opts.filename;
66
+ }
67
+
68
+ meta.component =
69
+ meta.component && resolveRelativePath(file, meta.component);
70
+ meta.deps = meta.deps.map(filename =>
71
+ typeof filename === "string"
72
+ ? resolveRelativePath(file, filename)
73
+ : filename
74
+ );
75
+
76
+ meta.imports = program.node.body
77
+ .filter(child => t.isImportDeclaration(child))
78
+ .map(child => child.source.value);
79
+ }
80
+ },
81
+ MarkoTag(tag) {
82
+ const { file } = tag.hub;
83
+ const tagDef = getTagDef(tag);
84
+ // Check if tag uses stateful tag params.
85
+ const meta = tag.hub.file.metadata.marko;
86
+
87
+ if (tagDef) {
88
+ if (tagDef.html && !tagDef.template && !tagDef.renderer) {
89
+ if (tagDef.htmlType === "custom-element") {
90
+ if (tagDef.parseOptions && tagDef.parseOptions.import) {
91
+ // TODO: the taglib should be updated to support this as a top level option.
92
+ meta.deps.push(
93
+ resolve(
94
+ tagDef.dir,
95
+ resolve(tagDef.dir, tagDef.parseOptions.import)
96
+ )
97
+ );
98
+ }
99
+ }
100
+ } else if (tag.get("name").isStringLiteral()) {
101
+ const relativePath = resolveRelativeTagEntry(file, tagDef);
102
+
103
+ if (relativePath) {
104
+ tag.node.extra = tag.node.extra || {};
105
+ tag.node.extra.relativePath = relativePath;
106
+
107
+ if (!meta.tags.includes(relativePath)) {
108
+ meta.tags.push(relativePath);
109
+ }
110
+ }
111
+ }
112
+
113
+ if (tagDef.translator && tagDef.translator.path) {
114
+ if (!meta.watchFiles.includes(tagDef.translator.path)) {
115
+ meta.watchFiles.push(tagDef.translator.path);
116
+ }
117
+ }
118
+ }
119
+
120
+ if (
121
+ meta.hasStatefulTagParams ||
122
+ isNativeTag(tag) ||
123
+ isMacroTag(tag) ||
124
+ !tag.get("body").get("params").length
125
+ ) {
126
+ return;
127
+ }
128
+
129
+ if (isDynamicTag(tag)) {
130
+ meta.hasStatefulTagParams = true;
131
+ return;
132
+ }
133
+
134
+ let curTag = tag;
135
+ while (isAttributeTag(curTag)) {
136
+ curTag = findParentTag(curTag);
137
+ }
138
+
139
+ const tagFile = loadFileForTag(curTag);
140
+ const childMeta = tagFile && tagFile.metadata.marko;
141
+ meta.hasStatefulTagParams =
142
+ childMeta &&
143
+ (childMeta.hasStatefulTagParams ||
144
+ (childMeta.hasComponent && !childMeta.hasComponentBrowser));
145
+ },
146
+ ImportDeclaration: {
147
+ exit(path) {
148
+ const source = path.get("source");
149
+ const tagEntry = resolveTagImport(source, source.node.value);
150
+
151
+ if (tagEntry) {
152
+ const meta = path.hub.file.metadata.marko;
153
+ source.node.value = tagEntry;
154
+
155
+ if (!meta.tags.includes(tagEntry)) {
156
+ meta.tags.push(tagEntry);
157
+ }
158
+ }
159
+ }
160
+ }
161
+ };
162
+
163
+ export const translate = {
164
+ MarkoDocumentType,
165
+ MarkoDeclaration,
166
+ MarkoCDATA,
167
+ MarkoTag,
168
+ MarkoText,
169
+ MarkoPlaceholder,
170
+ MarkoScriptlet,
171
+ MarkoClass,
172
+ MarkoComment,
173
+ ReferencedIdentifier(path) {
174
+ if (path.node.name === "component" && !path.scope.hasBinding("component")) {
175
+ path.replaceWith(path.hub.file._componentInstanceIdentifier);
176
+ }
177
+ },
178
+ Program: {
179
+ enter(path) {
180
+ const {
181
+ hub: { file }
182
+ } = path;
183
+
184
+ if (file.markoOpts.output === "hydrate") {
185
+ addDependencies(file, true);
186
+ return;
187
+ } else if (
188
+ file.markoOpts.resolveVirtualDependency &&
189
+ file.markoOpts.output !== "html"
190
+ ) {
191
+ addDependencies(file, false);
192
+ }
193
+
194
+ if (file.metadata.marko.moduleCode) {
195
+ path
196
+ .replaceWith(parseScript(file, file.metadata.marko.moduleCode))[0]
197
+ .skip();
198
+ return;
199
+ }
200
+
201
+ file._componentDefIdentifier =
202
+ path.scope.generateUidIdentifier("componentDef");
203
+
204
+ file._componentInstanceIdentifier =
205
+ path.scope.generateUidIdentifier("component");
206
+
207
+ // Pre-Analyze tree
208
+ analyzeStaticVDOM(path);
209
+
210
+ // Move non static content into the renderBody.
211
+ const [renderBlock] = path.pushContainer("body", t.blockStatement([]));
212
+ path
213
+ .get("body")
214
+ .filter(isRenderContent)
215
+ .forEach(childPath => {
216
+ renderBlock.pushContainer("body", childPath.node);
217
+ childPath.remove();
218
+ });
219
+
220
+ file._renderBlock = renderBlock;
221
+ path.scope.crawl();
222
+ },
223
+ exit(path) {
224
+ const {
225
+ hub: { file }
226
+ } = path;
227
+ const { markoOpts, _inlineComponentClass } = file;
228
+ const includeMetaInSource = markoOpts.meta !== false;
229
+ const meta = file.metadata.marko;
230
+ const { componentFile, componentBrowserFile } = getComponentFiles(path);
231
+ const isHTML = markoOpts.output === "html";
232
+
233
+ const renderBlock = file._renderBlock;
234
+ const componentClass =
235
+ (componentFile &&
236
+ importDefault(
237
+ file,
238
+ resolveRelativePath(file, componentFile),
239
+ "marko_component"
240
+ )) ||
241
+ _inlineComponentClass ||
242
+ t.objectExpression([]);
243
+
244
+ const componentIdentifier =
245
+ path.scope.generateUidIdentifier("marko_component");
246
+ const componentTypeIdentifier = path.scope.generateUidIdentifier(
247
+ "marko_componentType"
248
+ );
249
+ const templateIdentifier =
250
+ path.scope.generateUidIdentifier("marko_template");
251
+ const rendererIdentifier = importDefault(
252
+ file,
253
+ "marko/src/runtime/components/renderer.js",
254
+ "marko_renderer"
255
+ );
256
+ const templateRendererMember = t.memberExpression(
257
+ templateIdentifier,
258
+ t.identifier("_")
259
+ );
260
+ const templateMetaMember = t.memberExpression(
261
+ templateIdentifier,
262
+ t.identifier("meta")
263
+ );
264
+
265
+ if (markoOpts.writeVersionComment) {
266
+ path.addComment(
267
+ "leading",
268
+ ` Compiled using marko@${version} - DO NOT EDIT`,
269
+ true
270
+ );
271
+ }
272
+
273
+ const runtimeTemplateIdentifier = path.scope.generateUidIdentifier("t");
274
+
275
+ path.unshiftContainer(
276
+ "body",
277
+ [
278
+ t.importDeclaration(
279
+ [t.importSpecifier(runtimeTemplateIdentifier, t.identifier("t"))],
280
+ t.stringLiteral(
281
+ `marko/${markoOpts.optimize ? "dist" : "src"}/runtime/${
282
+ isHTML ? "html" : "vdom"
283
+ }/${markoOpts.hot ? "hot-reload.js" : "index.js"}`
284
+ )
285
+ ),
286
+ t.variableDeclaration("const", [
287
+ t.variableDeclarator(
288
+ componentTypeIdentifier,
289
+ t.stringLiteral(meta.id)
290
+ ),
291
+ t.variableDeclarator(
292
+ templateIdentifier,
293
+ t.callExpression(runtimeTemplateIdentifier, [
294
+ componentTypeIdentifier
295
+ ])
296
+ )
297
+ ]),
298
+ includeMetaInSource &&
299
+ t.expressionStatement(
300
+ t.assignmentExpression(
301
+ "=",
302
+ t.memberExpression(templateIdentifier, t.identifier("path")),
303
+ t.identifier("__filename")
304
+ )
305
+ ),
306
+ t.exportDefaultDeclaration(templateIdentifier)
307
+ ].filter(Boolean)
308
+ );
309
+
310
+ path.pushContainer(
311
+ "body",
312
+ [
313
+ !isHTML &&
314
+ t.expressionStatement(
315
+ t.callExpression(
316
+ importNamed(
317
+ file,
318
+ "marko/src/runtime/components/registry",
319
+ "r",
320
+ "marko_registerComponent"
321
+ ),
322
+ [
323
+ componentTypeIdentifier,
324
+ t.arrowFunctionExpression(
325
+ [],
326
+ componentBrowserFile
327
+ ? importDefault(
328
+ file,
329
+ resolveRelativePath(file, componentBrowserFile),
330
+ "marko_split_component"
331
+ )
332
+ : templateIdentifier
333
+ )
334
+ ]
335
+ )
336
+ ),
337
+ t.variableDeclaration("const", [
338
+ t.variableDeclarator(componentIdentifier, componentClass)
339
+ ])
340
+ ].filter(Boolean)
341
+ );
342
+
343
+ const templateRenderOptionsProps = [
344
+ t.objectProperty(t.identifier("t"), componentTypeIdentifier)
345
+ ];
346
+
347
+ if (!meta.component) {
348
+ templateRenderOptionsProps.push(
349
+ t.objectProperty(t.identifier("i"), t.booleanLiteral(true))
350
+ );
351
+ }
352
+
353
+ if (componentBrowserFile) {
354
+ templateRenderOptionsProps.push(
355
+ t.objectProperty(t.identifier("s"), t.booleanLiteral(true))
356
+ );
357
+ }
358
+
359
+ if (!markoOpts.optimize) {
360
+ templateRenderOptionsProps.push(
361
+ t.objectProperty(t.identifier("d"), t.booleanLiteral(true))
362
+ );
363
+ }
364
+
365
+ path.pushContainer(
366
+ "body",
367
+ t.expressionStatement(
368
+ t.assignmentExpression(
369
+ "=",
370
+ templateRendererMember,
371
+ t.callExpression(rendererIdentifier, [
372
+ t.functionExpression(
373
+ null,
374
+ [
375
+ t.identifier("input"),
376
+ t.identifier("out"),
377
+ file._componentDefIdentifier,
378
+ file._componentInstanceIdentifier,
379
+ t.identifier("state"),
380
+ t.identifier("$global")
381
+ ],
382
+ renderBlock.node
383
+ ),
384
+ t.objectExpression(templateRenderOptionsProps),
385
+ componentIdentifier
386
+ ])
387
+ )
388
+ )
389
+ );
390
+ renderBlock.remove();
391
+
392
+ if (!isHTML) {
393
+ path.pushContainer(
394
+ "body",
395
+ t.expressionStatement(
396
+ t.assignmentExpression(
397
+ "=",
398
+ t.memberExpression(templateIdentifier, t.identifier("Component")),
399
+ t.callExpression(
400
+ importDefault(
401
+ file,
402
+ "marko/src/runtime/components/defineComponent.js",
403
+ "marko_defineComponent"
404
+ ),
405
+ [componentIdentifier, templateRendererMember]
406
+ )
407
+ )
408
+ )
409
+ );
410
+ }
411
+
412
+ if (includeMetaInSource) {
413
+ const metaObject = t.objectExpression([
414
+ t.objectProperty(t.identifier("id"), componentTypeIdentifier)
415
+ ]);
416
+
417
+ if (meta.component) {
418
+ metaObject.properties.push(
419
+ t.objectProperty(
420
+ t.identifier("component"),
421
+ t.stringLiteral(meta.component)
422
+ )
423
+ );
424
+ }
425
+
426
+ if (meta.deps.length) {
427
+ metaObject.properties.push(
428
+ t.objectProperty(
429
+ t.identifier("deps"),
430
+ parseExpression(file, JSON.stringify(meta.deps), file.code.length)
431
+ )
432
+ );
433
+ }
434
+
435
+ if (meta.tags.length) {
436
+ metaObject.properties.push(
437
+ t.objectProperty(
438
+ t.identifier("tags"),
439
+ t.arrayExpression(meta.tags.map(tag => t.stringLiteral(tag)))
440
+ )
441
+ );
442
+ }
443
+
444
+ path.pushContainer(
445
+ "body",
446
+ t.expressionStatement(
447
+ t.assignmentExpression("=", templateMetaMember, metaObject)
448
+ )
449
+ );
450
+ }
451
+
452
+ optimizeHTMLWrites(path);
453
+ }
454
+ }
455
+ };
456
+
457
+ export function getRuntimeEntryFiles(output, optimize) {
458
+ const base = `marko/${optimize ? "dist" : "src"}/`;
459
+
460
+ return [
461
+ `${base}runtime/components/index.js`,
462
+ `${base}runtime/components/defineComponent.js`,
463
+ `${base}runtime/components/renderer.js`,
464
+ `${base}runtime/components/registry.js`,
465
+ `${base}runtime/components/attach-detach.js`,
466
+ `${base}runtime/helpers/assign.js`,
467
+ `${base}runtime/helpers/class-value.js`,
468
+ `${base}runtime/helpers/dynamic-tag.js`,
469
+ `${base}runtime/helpers/load-nested-tag.js`,
470
+ `${base}runtime/helpers/merge.js`,
471
+ `${base}runtime/helpers/repeatable.js`,
472
+ `${base}runtime/helpers/self-iterator.js`,
473
+ `${base}runtime/helpers/render-tag.js`,
474
+ `${base}runtime/helpers/style-value.js`,
475
+ `${base}runtime/helpers/to-string.js`,
476
+ `${base}core-tags/components/preserve-tag.js`,
477
+ ...(output === "html"
478
+ ? [
479
+ `${base}runtime/html/index.js`,
480
+ `${base}runtime/html/hot-reload.js`,
481
+ `${base}runtime/html/helpers/attr.js`,
482
+ `${base}runtime/html/helpers/attrs.js`,
483
+ `${base}runtime/html/helpers/class-attr.js`,
484
+ `${base}runtime/html/helpers/data-marko.js`,
485
+ `${base}runtime/html/helpers/escape-quotes.js`,
486
+ `${base}runtime/html/helpers/escape-script-placeholder.js`,
487
+ `${base}runtime/html/helpers/escape-style-placeholder.js`,
488
+ `${base}runtime/html/helpers/escape-xml.js`,
489
+ `${base}runtime/html/helpers/merge-attrs.js`,
490
+ `${base}runtime/html/helpers/props-script.js`,
491
+ `${base}runtime/html/helpers/style-attr.js`,
492
+ `${base}core-tags/components/init-components-tag.js`,
493
+ `${base}core-tags/components/preferred-script-location-tag.js`,
494
+ `${base}core-tags/core/__flush_here_and_after__.js`,
495
+ `${base}core-tags/core/await/renderer.js`,
496
+ `${base}core-tags/core/await/reorderer-renderer.js`
497
+ ]
498
+ : [
499
+ `${base}runtime/vdom/index.js`,
500
+ `${base}runtime/vdom/hot-reload.js`,
501
+ `${base}runtime/vdom/helpers/attrs.js`,
502
+ `${base}runtime/vdom/helpers/const.js`,
503
+ `${base}runtime/vdom/helpers/v-element.js`,
504
+ `${base}runtime/vdom/helpers/v-text.js`,
505
+ `${base}runtime/vdom/preserve-attrs.js`
506
+ ])
507
+ ];
508
+ }
509
+
510
+ function isRenderContent(path) {
511
+ const { node } = path;
512
+ return t.MARKO_TYPES.includes(node.type) && !node.static;
513
+ }
514
+
515
+ function resolveRelativeTagEntry(file, tagDef) {
516
+ // TODO: support transform and other entries.
517
+ const entry = tagDef.template || tagDef.renderer;
518
+ return entry && resolveRelativePath(file, entry);
519
+ }