marko 5.36.5 → 5.37.0

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 (244) hide show
  1. package/dist/compiler/index.js +11 -11
  2. package/dist/core-tags/components/init-components-tag.js +4 -4
  3. package/dist/core-tags/components/preferred-script-location-tag.js +2 -2
  4. package/dist/core-tags/core/__flush_here_and_after__.js +1 -1
  5. package/dist/core-tags/core/await/AsyncValue.js +21 -21
  6. package/dist/core-tags/core/await/renderer.js +24 -24
  7. package/dist/core-tags/core/await/reorderer-renderer.js +6 -6
  8. package/dist/node-require/browser-refresh.js +18 -1
  9. package/dist/node-require/index.js +7 -7
  10. package/dist/node_modules/@internal/components-beginComponent/index-browser.js +5 -5
  11. package/dist/node_modules/@internal/components-beginComponent/index.js +12 -12
  12. package/dist/node_modules/@internal/components-define-widget-legacy/index-browser.js +99 -99
  13. package/dist/node_modules/@internal/components-define-widget-legacy/index.js +3 -3
  14. package/dist/node_modules/@internal/components-endComponent/index.js +3 -3
  15. package/dist/node_modules/@internal/components-entry/index-browser.js +2 -2
  16. package/dist/node_modules/@internal/components-entry/index.js +29 -29
  17. package/dist/node_modules/@internal/components-entry-legacy/index-browser.js +13 -13
  18. package/dist/node_modules/@internal/components-entry-legacy/index.js +1 -1
  19. package/dist/node_modules/@internal/components-registry/index-browser.js +102 -102
  20. package/dist/node_modules/@internal/components-registry/index.js +2 -2
  21. package/dist/node_modules/@internal/components-util/index-browser.js +20 -20
  22. package/dist/node_modules/@internal/components-util/index.js +24 -20
  23. package/dist/node_modules/@internal/create-readable/index-browser.js +1 -1
  24. package/dist/node_modules/@internal/create-readable/index.js +9 -9
  25. package/dist/node_modules/@internal/preserve-tag/index-browser.js +8 -8
  26. package/dist/node_modules/@internal/preserve-tag/index.js +6 -6
  27. package/dist/node_modules/@internal/set-immediate/index-browser.js +2 -2
  28. package/dist/node_modules/@internal/set-immediate/index-worker.js +3 -3
  29. package/dist/node_modules/@internal/set-immediate/index.js +3 -3
  30. package/dist/runtime/RenderResult.js +24 -24
  31. package/dist/runtime/components/Component.js +163 -163
  32. package/dist/runtime/components/ComponentDef.js +34 -34
  33. package/dist/runtime/components/ComponentsContext.js +20 -20
  34. package/dist/runtime/components/GlobalComponentsContext.js +4 -4
  35. package/dist/runtime/components/KeySequence.js +3 -3
  36. package/dist/runtime/components/ServerComponent.js +17 -17
  37. package/dist/runtime/components/State.js +28 -28
  38. package/dist/runtime/components/attach-detach.js +8 -8
  39. package/dist/runtime/components/defineComponent.js +5 -5
  40. package/dist/runtime/components/dom-data.js +6 -6
  41. package/dist/runtime/components/event-delegation.js +10 -10
  42. package/dist/runtime/components/legacy/defineComponent-legacy.js +1 -1
  43. package/dist/runtime/components/legacy/defineRenderer-legacy.js +25 -25
  44. package/dist/runtime/components/legacy/dependencies/index.js +10 -10
  45. package/dist/runtime/components/legacy/renderer-legacy.js +56 -56
  46. package/dist/runtime/components/renderer.js +45 -45
  47. package/dist/runtime/components/update-manager.js +4 -4
  48. package/dist/runtime/createOut.js +1 -1
  49. package/dist/runtime/dom-insert.js +5 -5
  50. package/dist/runtime/helpers/_change-case.js +2 -2
  51. package/dist/runtime/helpers/dynamic-tag.js +33 -33
  52. package/dist/runtime/helpers/render-tag.js +1 -1
  53. package/dist/runtime/helpers/serialize-noop.js +2 -2
  54. package/dist/runtime/helpers/style-value.js +1 -1
  55. package/dist/runtime/helpers/tags-compat/runtime-dom.js +35 -35
  56. package/dist/runtime/helpers/tags-compat/runtime-html.js +16 -16
  57. package/dist/runtime/html/AsyncStream.js +28 -28
  58. package/dist/runtime/html/BufferedWriter.js +2 -2
  59. package/dist/runtime/html/StringWriter.js +2 -2
  60. package/dist/runtime/html/helpers/_dynamic-attr.js +2 -2
  61. package/dist/runtime/html/helpers/attr.js +11 -11
  62. package/dist/runtime/html/helpers/attrs.js +6 -6
  63. package/dist/runtime/html/helpers/data-marko.js +6 -6
  64. package/dist/runtime/html/helpers/escape-quotes.js +2 -2
  65. package/dist/runtime/html/helpers/escape-xml.js +1 -1
  66. package/dist/runtime/html/helpers/merge-attrs.js +11 -11
  67. package/dist/runtime/html/helpers/props-script.js +1 -1
  68. package/dist/runtime/html/index.js +2 -2
  69. package/dist/runtime/renderable.js +5 -5
  70. package/dist/runtime/vdom/AsyncVDOMBuilder.js +100 -100
  71. package/dist/runtime/vdom/VComment.js +7 -7
  72. package/dist/runtime/vdom/VComponent.js +5 -5
  73. package/dist/runtime/vdom/VDocumentFragment.js +8 -8
  74. package/dist/runtime/vdom/VElement.js +52 -52
  75. package/dist/runtime/vdom/VFragment.js +9 -9
  76. package/dist/runtime/vdom/VNode.js +34 -34
  77. package/dist/runtime/vdom/VText.js +8 -8
  78. package/dist/runtime/vdom/helpers/attrs.js +6 -6
  79. package/dist/runtime/vdom/helpers/const-element.js +3 -3
  80. package/dist/runtime/vdom/hot-reload.js +20 -20
  81. package/dist/runtime/vdom/index.js +2 -2
  82. package/dist/runtime/vdom/morphdom/fragment.js +10 -10
  83. package/dist/runtime/vdom/morphdom/helpers.js +5 -5
  84. package/dist/runtime/vdom/morphdom/index.js +81 -81
  85. package/dist/runtime/vdom/vdom.js +15 -15
  86. package/dist/taglib/index.js +7 -7
  87. package/dist/translator/cdata/index.js +15 -0
  88. package/dist/translator/cdata/index[html].js +15 -0
  89. package/dist/translator/cdata/index[vdom].js +12 -0
  90. package/dist/translator/class.js +65 -0
  91. package/dist/translator/comment/index.js +15 -0
  92. package/dist/translator/comment/index[html].js +17 -0
  93. package/dist/translator/comment/index[vdom].js +3 -0
  94. package/dist/translator/declaration/index.js +15 -0
  95. package/dist/translator/declaration/index[html].js +12 -0
  96. package/dist/translator/declaration/index[vdom].js +3 -0
  97. package/dist/translator/document-type/index.js +15 -0
  98. package/dist/translator/document-type/index[html].js +12 -0
  99. package/dist/translator/document-type/index[vdom].js +3 -0
  100. package/dist/translator/index.js +551 -0
  101. package/dist/translator/placeholder/index.js +15 -0
  102. package/dist/translator/placeholder/index[html].js +93 -0
  103. package/dist/translator/placeholder/index[vdom].js +22 -0
  104. package/dist/translator/scriptlet.js +4 -0
  105. package/dist/translator/tag/attribute/directives/class.js +42 -0
  106. package/dist/translator/tag/attribute/directives/index.js +15 -0
  107. package/dist/translator/tag/attribute/directives/no-update-body-if.js +15 -0
  108. package/dist/translator/tag/attribute/directives/no-update-body.js +10 -0
  109. package/dist/translator/tag/attribute/directives/no-update-if.js +12 -0
  110. package/dist/translator/tag/attribute/directives/no-update.js +48 -0
  111. package/dist/translator/tag/attribute/directives/style.js +42 -0
  112. package/dist/translator/tag/attribute/index.js +150 -0
  113. package/dist/translator/tag/attribute/modifiers/index.js +7 -0
  114. package/dist/translator/tag/attribute/modifiers/no-update.js +14 -0
  115. package/dist/translator/tag/attribute/modifiers/scoped.js +23 -0
  116. package/dist/translator/tag/attribute-tag.js +149 -0
  117. package/dist/translator/tag/custom-tag.js +146 -0
  118. package/dist/translator/tag/dynamic-tag.js +74 -0
  119. package/dist/translator/tag/index.js +287 -0
  120. package/dist/translator/tag/macro-tag.js +7 -0
  121. package/dist/translator/tag/native-tag.js +27 -0
  122. package/dist/translator/tag/native-tag[html]/attributes.js +151 -0
  123. package/dist/translator/tag/native-tag[html]/index.js +221 -0
  124. package/dist/translator/tag/native-tag[vdom]/attributes.js +105 -0
  125. package/dist/translator/tag/native-tag[vdom]/index.js +189 -0
  126. package/dist/translator/tag/util.js +246 -0
  127. package/dist/translator/taglib/core/conditional/translate-else-if.js +20 -0
  128. package/dist/translator/taglib/core/conditional/translate-else.js +20 -0
  129. package/dist/translator/taglib/core/conditional/translate-if.js +8 -0
  130. package/dist/translator/taglib/core/conditional/util.js +41 -0
  131. package/dist/translator/taglib/core/index.js +474 -0
  132. package/dist/translator/taglib/core/macro/parse.js +17 -0
  133. package/dist/translator/taglib/core/macro/translate.js +48 -0
  134. package/dist/translator/taglib/core/parse-class.js +79 -0
  135. package/dist/translator/taglib/core/parse-export.js +14 -0
  136. package/dist/translator/taglib/core/parse-import.js +14 -0
  137. package/dist/translator/taglib/core/parse-module-code.js +18 -0
  138. package/dist/translator/taglib/core/parse-static.js +18 -0
  139. package/dist/translator/taglib/core/transform-style.js +66 -0
  140. package/dist/translator/taglib/core/translate-await.js +41 -0
  141. package/dist/translator/taglib/core/translate-body.js +17 -0
  142. package/dist/translator/taglib/core/translate-for.js +156 -0
  143. package/dist/translator/taglib/core/translate-html-comment.js +52 -0
  144. package/dist/translator/taglib/core/translate-include-content.js +53 -0
  145. package/dist/translator/taglib/core/translate-server-only.js +5 -0
  146. package/dist/translator/taglib/core/translate-while.js +32 -0
  147. package/dist/translator/taglib/index.js +6 -0
  148. package/dist/translator/taglib/migrate/all-templates.js +46 -0
  149. package/dist/translator/taglib/migrate/index.js +5 -0
  150. package/dist/translator/text/index.js +10 -0
  151. package/dist/translator/text/index[html].js +12 -0
  152. package/dist/translator/text/index[vdom].js +20 -0
  153. package/dist/translator/util/add-dependencies.js +329 -0
  154. package/dist/translator/util/escape-regexp.js +4 -0
  155. package/dist/translator/util/get-component-files.js +86 -0
  156. package/dist/translator/util/html-out-write.js +15 -0
  157. package/dist/translator/util/key-manager.js +176 -0
  158. package/dist/translator/util/optimize-html-writes.js +52 -0
  159. package/dist/translator/util/optimize-vdom-create.js +164 -0
  160. package/dist/translator/util/plugin-hooks.js +22 -0
  161. package/dist/translator/util/runtime-flags.js +3 -0
  162. package/dist/translator/util/vdom-out-write.js +10 -0
  163. package/dist/translator/util/with-previous-location.js +6 -0
  164. package/package.json +7 -4
  165. package/src/taglib/index.js +2 -2
  166. package/src/translator/cdata/index.js +15 -0
  167. package/src/translator/cdata/index[html].js +15 -0
  168. package/src/translator/cdata/index[vdom].js +12 -0
  169. package/src/translator/class.js +65 -0
  170. package/src/translator/comment/index.js +15 -0
  171. package/src/translator/comment/index[html].js +17 -0
  172. package/src/translator/comment/index[vdom].js +3 -0
  173. package/src/translator/declaration/index.js +15 -0
  174. package/src/translator/declaration/index[html].js +12 -0
  175. package/src/translator/declaration/index[vdom].js +3 -0
  176. package/src/translator/document-type/index.js +15 -0
  177. package/src/translator/document-type/index[html].js +12 -0
  178. package/src/translator/document-type/index[vdom].js +3 -0
  179. package/src/translator/index.js +551 -0
  180. package/src/translator/placeholder/index.js +15 -0
  181. package/src/translator/placeholder/index[html].js +93 -0
  182. package/src/translator/placeholder/index[vdom].js +22 -0
  183. package/src/translator/scriptlet.js +4 -0
  184. package/src/translator/tag/attribute/directives/class.js +42 -0
  185. package/src/translator/tag/attribute/directives/index.js +15 -0
  186. package/src/translator/tag/attribute/directives/no-update-body-if.js +15 -0
  187. package/src/translator/tag/attribute/directives/no-update-body.js +10 -0
  188. package/src/translator/tag/attribute/directives/no-update-if.js +12 -0
  189. package/src/translator/tag/attribute/directives/no-update.js +48 -0
  190. package/src/translator/tag/attribute/directives/style.js +42 -0
  191. package/src/translator/tag/attribute/index.js +150 -0
  192. package/src/translator/tag/attribute/modifiers/index.js +7 -0
  193. package/src/translator/tag/attribute/modifiers/no-update.js +14 -0
  194. package/src/translator/tag/attribute/modifiers/scoped.js +23 -0
  195. package/src/translator/tag/attribute-tag.js +149 -0
  196. package/src/translator/tag/custom-tag.js +146 -0
  197. package/src/translator/tag/dynamic-tag.js +74 -0
  198. package/src/translator/tag/index.js +287 -0
  199. package/src/translator/tag/macro-tag.js +7 -0
  200. package/src/translator/tag/native-tag.js +27 -0
  201. package/src/translator/tag/native-tag[html]/attributes.js +151 -0
  202. package/src/translator/tag/native-tag[html]/index.js +221 -0
  203. package/src/translator/tag/native-tag[vdom]/attributes.js +105 -0
  204. package/src/translator/tag/native-tag[vdom]/index.js +189 -0
  205. package/src/translator/tag/util.js +246 -0
  206. package/src/translator/taglib/core/conditional/translate-else-if.js +20 -0
  207. package/src/translator/taglib/core/conditional/translate-else.js +20 -0
  208. package/src/translator/taglib/core/conditional/translate-if.js +8 -0
  209. package/src/translator/taglib/core/conditional/util.js +41 -0
  210. package/src/translator/taglib/core/index.js +474 -0
  211. package/src/translator/taglib/core/macro/parse.js +17 -0
  212. package/src/translator/taglib/core/macro/translate.js +48 -0
  213. package/src/translator/taglib/core/parse-class.js +79 -0
  214. package/src/translator/taglib/core/parse-export.js +14 -0
  215. package/src/translator/taglib/core/parse-import.js +14 -0
  216. package/src/translator/taglib/core/parse-module-code.js +18 -0
  217. package/src/translator/taglib/core/parse-static.js +18 -0
  218. package/src/translator/taglib/core/transform-style.js +66 -0
  219. package/src/translator/taglib/core/translate-await.js +41 -0
  220. package/src/translator/taglib/core/translate-body.js +17 -0
  221. package/src/translator/taglib/core/translate-for.js +156 -0
  222. package/src/translator/taglib/core/translate-html-comment.js +52 -0
  223. package/src/translator/taglib/core/translate-include-content.js +53 -0
  224. package/src/translator/taglib/core/translate-server-only.js +5 -0
  225. package/src/translator/taglib/core/translate-while.js +32 -0
  226. package/src/translator/taglib/index.js +7 -0
  227. package/src/translator/taglib/migrate/all-templates.js +46 -0
  228. package/src/translator/taglib/migrate/index.js +5 -0
  229. package/src/translator/text/index.js +10 -0
  230. package/src/translator/text/index[html].js +12 -0
  231. package/src/translator/text/index[vdom].js +20 -0
  232. package/src/translator/util/add-dependencies.js +329 -0
  233. package/src/translator/util/escape-regexp.js +4 -0
  234. package/src/translator/util/get-component-files.js +86 -0
  235. package/src/translator/util/html-out-write.js +15 -0
  236. package/src/translator/util/key-manager.js +176 -0
  237. package/src/translator/util/optimize-html-writes.js +52 -0
  238. package/src/translator/util/optimize-vdom-create.js +164 -0
  239. package/src/translator/util/plugin-hooks.js +22 -0
  240. package/src/translator/util/runtime-flags.js +3 -0
  241. package/src/translator/util/vdom-out-write.js +10 -0
  242. package/src/translator/util/with-previous-location.js +6 -0
  243. package/translator/index.d.ts +7 -0
  244. package/translator/package.json +5 -0
@@ -0,0 +1,42 @@
1
+ import { types as t } from "@marko/compiler";
2
+ import {
3
+ computeNode,
4
+ importDefault,
5
+ isNativeTag,
6
+ } from "@marko/compiler/babel-utils";
7
+ import classToString from "marko/src/runtime/helpers/class-value";
8
+
9
+ import withPreviousLocation from "../../../util/with-previous-location";
10
+
11
+ export default {
12
+ exit(tag, _, value) {
13
+ const {
14
+ hub: { file },
15
+ } = tag;
16
+ if (!isNativeTag(tag)) return;
17
+
18
+ const computed = computeNode(value.node);
19
+ if (computed) {
20
+ const str = classToString(computed.value);
21
+ if (str) {
22
+ value.replaceWith(t.stringLiteral(str));
23
+ } else {
24
+ value.parentPath.remove();
25
+ }
26
+ } else if (!value.isTemplateLiteral()) {
27
+ value.replaceWith(
28
+ withPreviousLocation(
29
+ t.callExpression(
30
+ importDefault(
31
+ file,
32
+ "marko/src/runtime/helpers/class-value.js",
33
+ "marko_class_merge",
34
+ ),
35
+ [value.node],
36
+ ),
37
+ value.node,
38
+ ),
39
+ );
40
+ }
41
+ },
42
+ };
@@ -0,0 +1,15 @@
1
+ import classPlugin from "./class";
2
+ import noUpdatePlugin from "./no-update";
3
+ import noUpdateBodyPlugin from "./no-update-body";
4
+ import noUpdateBodyIfPlugin from "./no-update-body-if";
5
+ import noUpdateIfPlugin from "./no-update-if";
6
+ import stylePlugin from "./style";
7
+
8
+ export default {
9
+ class: classPlugin,
10
+ style: stylePlugin,
11
+ "no-update": noUpdatePlugin,
12
+ "no-update-if": noUpdateIfPlugin,
13
+ "no-update-body": noUpdateBodyPlugin,
14
+ "no-update-body-if": noUpdateBodyIfPlugin,
15
+ };
@@ -0,0 +1,15 @@
1
+ import { getArgOrSequence } from "@marko/compiler/babel-utils";
2
+
3
+ import noUpdateTransform from "./no-update";
4
+
5
+ export default {
6
+ enter(tag) {
7
+ tag.node.isPreserved = true;
8
+ },
9
+ exit(tag, attr, value) {
10
+ noUpdateTransform.exit(tag, attr, value, {
11
+ if: getArgOrSequence(attr),
12
+ bodyOnly: true,
13
+ });
14
+ },
15
+ };
@@ -0,0 +1,10 @@
1
+ import noUpdateTransform from "./no-update";
2
+
3
+ export default {
4
+ enter(tag) {
5
+ tag.node.isPreserved = true;
6
+ },
7
+ exit(tag, attr, value) {
8
+ noUpdateTransform.exit(tag, attr, value, { bodyOnly: true });
9
+ },
10
+ };
@@ -0,0 +1,12 @@
1
+ import { getArgOrSequence } from "@marko/compiler/babel-utils";
2
+
3
+ import noUpdateTransform from "./no-update";
4
+
5
+ export default {
6
+ enter(tag) {
7
+ tag.node.isPreserved = true;
8
+ },
9
+ exit(tag, attr, value) {
10
+ noUpdateTransform.exit(tag, attr, value, { if: getArgOrSequence(attr) });
11
+ },
12
+ };
@@ -0,0 +1,48 @@
1
+ import { types as t } from "@marko/compiler";
2
+ import {
3
+ isNativeTag,
4
+ normalizeTemplateString,
5
+ } from "@marko/compiler/babel-utils";
6
+ const EMPTY_OBJECT = {};
7
+
8
+ export default {
9
+ enter(tag) {
10
+ tag.node.isPreserved = true;
11
+ },
12
+ exit(tag, attr, _, opts = EMPTY_OBJECT) {
13
+ attr.remove();
14
+ const { node } = tag;
15
+ const replacement = t.markoTag(
16
+ t.stringLiteral("_preserve"),
17
+ [],
18
+ opts.bodyOnly ? node.body : t.markoTagBody([node]),
19
+ );
20
+
21
+ if (isNativeTag(tag)) {
22
+ replacement.key = node.key;
23
+ replacement.attributes.push(
24
+ t.markoAttribute("n", t.booleanLiteral(true)),
25
+ );
26
+
27
+ if (opts.bodyOnly) {
28
+ replacement.attributes.push(
29
+ t.markoAttribute("b", t.booleanLiteral(true)),
30
+ );
31
+ }
32
+ } else {
33
+ replacement.key = normalizeTemplateString`p_${node.key}`;
34
+ }
35
+
36
+ replacement.isPreserved = true;
37
+
38
+ if (opts.if) {
39
+ replacement.attributes.push(t.markoAttribute("i", opts.if));
40
+ }
41
+
42
+ if (opts.bodyOnly) {
43
+ tag.set("body", t.markoTagBody([replacement]));
44
+ } else {
45
+ tag.replaceWith(replacement);
46
+ }
47
+ },
48
+ };
@@ -0,0 +1,42 @@
1
+ import { types as t } from "@marko/compiler";
2
+ import {
3
+ computeNode,
4
+ importDefault,
5
+ isNativeTag,
6
+ } from "@marko/compiler/babel-utils";
7
+ import styleToString from "marko/src/runtime/helpers/style-value";
8
+
9
+ import withPreviousLocation from "../../../util/with-previous-location";
10
+
11
+ export default {
12
+ exit(tag, _, value) {
13
+ const {
14
+ hub: { file },
15
+ } = tag;
16
+ if (!isNativeTag(tag)) return;
17
+
18
+ const computed = computeNode(value.node);
19
+ if (computed) {
20
+ const str = styleToString(computed.value);
21
+ if (str) {
22
+ value.replaceWith(t.stringLiteral(str));
23
+ } else {
24
+ value.parentPath.remove();
25
+ }
26
+ } else if (!value.isTemplateLiteral()) {
27
+ value.replaceWith(
28
+ withPreviousLocation(
29
+ t.callExpression(
30
+ importDefault(
31
+ file,
32
+ "marko/src/runtime/helpers/style-value.js",
33
+ "marko_style_merge",
34
+ ),
35
+ [value.node],
36
+ ),
37
+ value.node,
38
+ ),
39
+ );
40
+ }
41
+ },
42
+ };
@@ -0,0 +1,150 @@
1
+ import {
2
+ getTagDef,
3
+ importDefault,
4
+ isNativeTag,
5
+ } from "@marko/compiler/babel-utils";
6
+
7
+ import directives from "./directives";
8
+ import modifiers from "./modifiers";
9
+
10
+ const EMPTY_ARRAY = [];
11
+ const EVENT_REG = /^(on(?:ce)?)(-)?(.*)$/;
12
+ const attachedDetachedLoaded = new WeakSet();
13
+
14
+ export default {
15
+ enter(attr) {
16
+ const {
17
+ hub: { file },
18
+ } = attr;
19
+ const tag = attr.parentPath;
20
+ const value = attr.get("value");
21
+ const { name, arguments: args } = attr.node;
22
+ const isVDOM = file.markoOpts.output !== "html";
23
+
24
+ if (execModifiersAndDirectives("enter", tag, attr, value)) {
25
+ return;
26
+ }
27
+
28
+ // Event handlers.
29
+ let [, eventType, isDash, eventName] = EVENT_REG.exec(name) || EMPTY_ARRAY;
30
+
31
+ if (eventType && args) {
32
+ if (!args.length) {
33
+ throw attr.buildCodeFrameError("Event handler is missing arguments.");
34
+ }
35
+
36
+ if (!value.isBooleanLiteral(true)) {
37
+ throw value.buildCodeFrameError(
38
+ `"${name}(handler, ...args)" does not accept a value.`,
39
+ );
40
+ }
41
+
42
+ if (!isDash) {
43
+ // When the event is not in dash case we normalized differently for html tags and custom tags.
44
+
45
+ if (isNativeTag(tag)) {
46
+ // Lowercase the string
47
+ // Example: onMouseOver → mouseover
48
+ eventName = eventName.toLowerCase();
49
+ } else {
50
+ // Convert first character to lower case:
51
+ // Example: onBeforeShow → beforeShow
52
+ eventName = eventName.charAt(0).toLowerCase() + eventName.slice(1);
53
+ }
54
+ }
55
+
56
+ const handlers = (tag.node.handlers = tag.node.handlers || {});
57
+ if (handlers[eventName]) {
58
+ throw attr.buildCodeFrameError(
59
+ "Duplicate event handlers are not supported.",
60
+ );
61
+ }
62
+
63
+ handlers[eventName] = {
64
+ arguments: args,
65
+ once: eventType === "once",
66
+ };
67
+
68
+ if (isVDOM) {
69
+ if (eventName === "attach" || eventName === "detach") {
70
+ if (!attachedDetachedLoaded.has(file)) {
71
+ // Pull in helper for element attach/detach;
72
+ attachedDetachedLoaded.add(file);
73
+ importDefault(
74
+ file,
75
+ "marko/src/runtime/components/attach-detach.js",
76
+ );
77
+ }
78
+ }
79
+ }
80
+
81
+ attr.remove();
82
+ return;
83
+ }
84
+ },
85
+ exit(attr) {
86
+ const tag = attr.parentPath;
87
+ const { name, arguments: args } = attr.node;
88
+ const value = attr.get("value");
89
+
90
+ if (execModifiersAndDirectives("exit", tag, attr, value)) {
91
+ return;
92
+ }
93
+
94
+ const tagDef = getTagDef(tag);
95
+
96
+ if (tagDef) {
97
+ if (!tagDef.html && !tagDef.getAttribute(name)) {
98
+ throw attr.buildCodeFrameError(
99
+ `<${
100
+ tag.get("name.value").node
101
+ }> does not support the "${name}" attribute.`,
102
+ );
103
+ }
104
+ }
105
+
106
+ if (args && args.length) {
107
+ throw attr.buildCodeFrameError(
108
+ `Unsupported arguments on the "${name}" attribute.`,
109
+ );
110
+ }
111
+
112
+ if (attr.node.bound) {
113
+ throw attr.buildCodeFrameError(
114
+ `The binding syntax (:=) is only supported when using the "Tags API".`,
115
+ );
116
+ }
117
+ },
118
+ };
119
+
120
+ function execModifiersAndDirectives(type, tag, attr, value) {
121
+ const { node } = attr;
122
+ const { name, modifier } = node;
123
+
124
+ if (modifier) {
125
+ const modifierTranslate = modifiers[modifier];
126
+ if (modifierTranslate) {
127
+ if (modifierTranslate[type]) {
128
+ const tagNode = tag.node;
129
+ const attrNode = attr.node;
130
+ modifierTranslate[type](tag, attr, value);
131
+ if (tag.node !== tagNode || attr.node !== attrNode) return true;
132
+ }
133
+ } else if (name === "xlink" && modifier === "href" && isNativeTag(tag)) {
134
+ node.name += `:${modifier}`;
135
+ node.modifier = undefined;
136
+ } else {
137
+ throw attr.buildCodeFrameError(`Unsupported modifier "${modifier}".`);
138
+ }
139
+ }
140
+
141
+ const directiveTranslate = directives[name];
142
+ if (directiveTranslate) {
143
+ if (directiveTranslate[type]) {
144
+ const tagNode = tag.node;
145
+ const attrNode = attr.node;
146
+ directiveTranslate[type](tag, attr, value);
147
+ if (tag.node !== tagNode || attr.node !== attrNode) return true;
148
+ }
149
+ }
150
+ }
@@ -0,0 +1,7 @@
1
+ import noUpdatePlugin from "./no-update";
2
+ import scopedPlugin from "./scoped";
3
+
4
+ export default {
5
+ scoped: scopedPlugin,
6
+ "no-update": noUpdatePlugin,
7
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Does nothing in html mode.
3
+ */
4
+ export default {
5
+ exit(tag, attr) {
6
+ const { node } = tag;
7
+
8
+ if (!node.preserveAttrs) {
9
+ node.preserveAttrs = [];
10
+ }
11
+
12
+ node.preserveAttrs.push(attr.node.name);
13
+ },
14
+ };
@@ -0,0 +1,23 @@
1
+ import { types as t } from "@marko/compiler";
2
+
3
+ import withPreviousLocation from "../../../util/with-previous-location";
4
+
5
+ export default {
6
+ exit(tag, _, value) {
7
+ const {
8
+ hub: { file },
9
+ } = tag;
10
+ value.replaceWith(
11
+ withPreviousLocation(
12
+ t.callExpression(
13
+ t.memberExpression(
14
+ file._componentDefIdentifier,
15
+ t.identifier("elId"),
16
+ ),
17
+ [value.node],
18
+ ),
19
+ value.node,
20
+ ),
21
+ );
22
+ },
23
+ };
@@ -0,0 +1,149 @@
1
+ import { types as t } from "@marko/compiler";
2
+ import {
3
+ assertNoArgs,
4
+ findParentTag,
5
+ getFullyResolvedTagName,
6
+ getTagDef,
7
+ importNamed,
8
+ isAttributeTag,
9
+ isTransparentTag,
10
+ } from "@marko/compiler/babel-utils";
11
+
12
+ import { getAttrs } from "./util";
13
+
14
+ const attributeTagsForTag = new WeakMap();
15
+ const contentTypeCache = new WeakMap();
16
+ const ContentType = {
17
+ attribute: 0,
18
+ render: 1,
19
+ mixed: 2,
20
+ };
21
+
22
+ export function analyzeAttributeTags(rootTag) {
23
+ const visit = [rootTag];
24
+ const parentTags = [rootTag];
25
+ let i = 0;
26
+ let attributeTags;
27
+
28
+ while (i < visit.length) {
29
+ const tag = visit[i++];
30
+ const attrTags = tag.node.body.attributeTags
31
+ ? tag.get("body").get("body")
32
+ : tag.get("attributeTags");
33
+ for (const child of attrTags) {
34
+ if (isAttributeTag(child)) {
35
+ assertNoArgs(child);
36
+ const tagDef = getTagDef(child) || {};
37
+ const name = getFullyResolvedTagName(child);
38
+ let {
39
+ targetProperty = child.node.name.value.slice(1),
40
+ isRepeated = false,
41
+ } = tagDef;
42
+
43
+ const preserveName =
44
+ tagDef.preserveName === true || tagDef.removeDashes === false;
45
+
46
+ if (!preserveName) {
47
+ targetProperty = removeDashes(targetProperty);
48
+ }
49
+
50
+ const attrTagMeta = ((attributeTags ||= {})[name] ||= {
51
+ targetProperty,
52
+ isRepeated,
53
+ });
54
+
55
+ (child.node.extra ||= {}).attributeTag = attrTagMeta;
56
+
57
+ const parentTag = findParentTag(child);
58
+ const parentTagExtra = (parentTag.node.extra ||= {});
59
+ const parentSeenAttributeTagProperties =
60
+ attributeTagsForTag.get(parentTag);
61
+ let hasAttributeTags = false;
62
+
63
+ if (!parentSeenAttributeTagProperties) {
64
+ parentTagExtra.hasAttributeTags = true;
65
+ attributeTagsForTag.set(parentTag, new Set([targetProperty]));
66
+ } else if (parentSeenAttributeTagProperties.has(targetProperty)) {
67
+ hasAttributeTags = true;
68
+ } else {
69
+ parentSeenAttributeTagProperties.add(targetProperty);
70
+ }
71
+
72
+ if (!hasAttributeTags) {
73
+ if (
74
+ parentTag
75
+ .get("attributes")
76
+ .some(
77
+ (attr) =>
78
+ attr.isMarkoSpreadAttribute() ||
79
+ attr.node.name === targetProperty,
80
+ )
81
+ ) {
82
+ parentTag.pushContainer(
83
+ "attributes",
84
+ t.markoAttribute(
85
+ targetProperty,
86
+ t.unaryExpression("void", t.numericLiteral(0)),
87
+ ),
88
+ );
89
+ }
90
+ }
91
+
92
+ parentTags.push(child);
93
+ visit.push(child);
94
+ } else if (isTransparentTag(child)) {
95
+ visit.push(child);
96
+ }
97
+ }
98
+ }
99
+
100
+ if (attributeTags) {
101
+ (rootTag.node.extra ??= {}).attributeTags = attributeTags;
102
+ }
103
+ }
104
+
105
+ export default function translateAttributeTag(tag) {
106
+ const { node } = tag;
107
+ const meta = node.extra?.attributeTag;
108
+ if (!meta) {
109
+ throw tag
110
+ .get("name")
111
+ .buildCodeFrameError("@tags must be nested within another element.");
112
+ }
113
+
114
+ assertNoArgs(tag);
115
+
116
+ tag.replaceWith(
117
+ t.expressionStatement(
118
+ t.callExpression(
119
+ importNamed(
120
+ tag.hub.file,
121
+ "marko/src/runtime/helpers/attr-tag.js",
122
+ meta.isRepeated ? "r" : "a",
123
+ meta.isRepeated
124
+ ? "marko_repeated_attr_tag"
125
+ : "marko_repeatable_attr_tag",
126
+ ),
127
+ [t.stringLiteral(meta.targetProperty), getAttrTagObject(tag)],
128
+ ),
129
+ ),
130
+ );
131
+ }
132
+
133
+ function getAttrTagObject(tag) {
134
+ const attrs = getAttrs(tag, false, true);
135
+
136
+ if (t.isNullLiteral(attrs)) {
137
+ return t.objectExpression([]);
138
+ }
139
+
140
+ return attrs;
141
+ }
142
+
143
+ function removeDashes(str) {
144
+ return str.replace(/-([a-z])/g, matchToUpperCase);
145
+ }
146
+
147
+ function matchToUpperCase(_match, lower) {
148
+ return lower.toUpperCase();
149
+ }
@@ -0,0 +1,146 @@
1
+ import { types as t } from "@marko/compiler";
2
+ import {
3
+ assertNoArgs,
4
+ getTagDef,
5
+ importDefault,
6
+ loadFileForTag,
7
+ resolveRelativePath,
8
+ resolveTagImport,
9
+ } from "@marko/compiler/babel-utils";
10
+
11
+ import withPreviousLocation from "../util/with-previous-location";
12
+ import dynamicTag from "./dynamic-tag";
13
+ import nativeTag from "./native-tag";
14
+ import { buildEventHandlerArray, getAttrs } from "./util";
15
+
16
+ export default function (path, isNullable) {
17
+ const {
18
+ hub: { file },
19
+ node,
20
+ } = path;
21
+ const { markoOpts } = file;
22
+ const { name, key } = node;
23
+
24
+ assertNoArgs(path);
25
+
26
+ let tagIdentifier;
27
+
28
+ if (t.isStringLiteral(name)) {
29
+ const tagName = name.value;
30
+ let relativePath = node.extra && node.extra.relativePath;
31
+
32
+ if (!relativePath) {
33
+ const tagDef = getTagDef(path);
34
+ if (tagDef && tagDef.renderer) {
35
+ // Normally new tags should not be added in the translate stage.
36
+ // We make an exception here for core tags, init-components & _preserve being the primary culprits.
37
+ // TODO: in the future refactor so this is not needed.
38
+ relativePath = resolveRelativePath(file, tagDef.renderer);
39
+ }
40
+ }
41
+
42
+ let binding = !relativePath && path.scope.getBinding(tagName);
43
+ if (binding && !binding.identifier.loc) binding = null;
44
+
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
+
74
+ tagIdentifier = importDefault(file, relativePath, tagName);
75
+ } else if (binding) {
76
+ path.set("name", t.identifier(tagName));
77
+ return dynamicTag(path);
78
+ } else if (markoOpts.ignoreUnrecognizedTags) {
79
+ return nativeTag(path);
80
+ } else {
81
+ throw path
82
+ .get("name")
83
+ .buildCodeFrameError(
84
+ `Unable to find entry point for custom tag <${tagName}>.`,
85
+ );
86
+ }
87
+ } else {
88
+ tagIdentifier = name;
89
+ }
90
+
91
+ const foundAttrs = getAttrs(path);
92
+ const customTagRenderCall = withPreviousLocation(
93
+ t.expressionStatement(
94
+ t.callExpression(
95
+ importDefault(
96
+ file,
97
+ "marko/src/runtime/helpers/render-tag.js",
98
+ "marko_tag",
99
+ ),
100
+ [
101
+ tagIdentifier,
102
+ // TODO: this could be left as null if we froze input mutations and used a default object in the runtime.
103
+ t.isNullLiteral(foundAttrs) ? t.objectExpression([]) : foundAttrs,
104
+ t.identifier("out"),
105
+ file._componentDefIdentifier,
106
+ key,
107
+ ...buildEventHandlerArray(path),
108
+ ],
109
+ ),
110
+ ),
111
+ node,
112
+ );
113
+
114
+ if (isNullable) {
115
+ let renderBodyIdentifier;
116
+ const renderBodyProp =
117
+ t.isObjectExpression(foundAttrs) &&
118
+ foundAttrs.properties.find(
119
+ (prop) => prop.key && prop.key.value === "renderBody",
120
+ );
121
+
122
+ if (renderBodyProp) {
123
+ renderBodyIdentifier = path.scope.generateUidIdentifier("renderBody");
124
+ path.insertBefore(
125
+ t.variableDeclaration("const", [
126
+ t.variableDeclarator(renderBodyIdentifier, renderBodyProp.value),
127
+ ]),
128
+ );
129
+
130
+ renderBodyProp.value = renderBodyIdentifier;
131
+ }
132
+
133
+ path.replaceWith(
134
+ t.ifStatement(
135
+ name,
136
+ customTagRenderCall,
137
+ renderBodyIdentifier &&
138
+ t.expressionStatement(
139
+ t.callExpression(renderBodyIdentifier, [t.identifier("out")]),
140
+ ),
141
+ ),
142
+ );
143
+ } else {
144
+ path.replaceWith(customTagRenderCall);
145
+ }
146
+ }