@marko/compiler 5.20.6 → 5.20.9

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.
@@ -1,10 +1,4 @@
1
- "use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule = true;exports.parseMarko = parseMarko;var _htmljsParser = require("htmljs-parser");
2
- var _parseAttributes = _interopRequireDefault(require("./util/parse-attributes"));
3
- var _parseArguments = _interopRequireDefault(require("./util/parse-arguments"));
4
- var _parseParams = _interopRequireDefault(require("./util/parse-params"));
5
- var _parseVar = _interopRequireDefault(require("./util/parse-var"));
6
- var _parseIdShorthand = _interopRequireDefault(require("./util/parse-id-shorthand"));
7
- var _parseClassnameShorthand = _interopRequireDefault(require("./util/parse-classname-shorthand"));
1
+ "use strict";exports.__esModule = true;exports.parseMarko = parseMarko;var _htmljsParser = require("htmljs-parser");
8
2
  var t = _interopRequireWildcard(require("../babel-types"));
9
3
  var _babelUtils = require("@marko/babel-utils");function _getRequireWildcardCache(nodeInterop) {if (typeof WeakMap !== "function") return null;var cacheBabelInterop = new WeakMap();var cacheNodeInterop = new WeakMap();return (_getRequireWildcardCache = function (nodeInterop) {return nodeInterop ? cacheNodeInterop : cacheBabelInterop;})(nodeInterop);}function _interopRequireWildcard(obj, nodeInterop) {if (!nodeInterop && obj && obj.__esModule) {return obj;}if (obj === null || typeof obj !== "object" && typeof obj !== "function") {return { default: obj };}var cache = _getRequireWildcardCache(nodeInterop);if (cache && cache.has(obj)) {return cache.get(obj);}var newObj = {};var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;for (var key in obj) {if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;if (desc && (desc.get || desc.set)) {Object.defineProperty(newObj, key, desc);} else {newObj[key] = obj[key];}}}newObj.default = obj;if (cache) {cache.set(obj, newObj);}return newObj;}
10
4
 
@@ -12,356 +6,475 @@ var _babelUtils = require("@marko/babel-utils");function _getRequireWildcardCach
12
6
 
13
7
 
14
8
 
9
+ const noop = () => {};
10
+ const emptyRange = (part) => part.start === part.end;
11
+ const isAttrTag = (tag) => {var _tag$name$value;return ((_tag$name$value = tag.name.value) == null ? void 0 : _tag$name$value[0]) === "@";};
12
+ const toBabelPosition = ({ line, character }) => ({
13
+ line: line + 1,
14
+ column: character ? character - 1 : character });
15
15
 
16
16
 
17
-
18
- const EMPTY_OBJECT = {};
19
- const EMPTY_ARRAY = [];
20
- const htmlTrimStart = (t) => t.replace(/^[\n\r]\s*/, "");
21
- const htmlTrimEnd = (t) => t.replace(/[\n\r]\s*$/, "");
22
- const htmlTrim = (t) => htmlTrimStart(htmlTrimEnd(t));
23
- const isAttributeTag = (node) =>
24
- t.isStringLiteral(node.name) && node.name.value[0] === "@";
25
-
26
17
  function parseMarko(file) {
27
18
  const { code } = file;
28
19
  const { htmlParseOptions = {} } = file.markoOpts;
29
20
  const { watchFiles } = file.metadata.marko;
30
- const pushTagBody = (node) => getTagBody().pushContainer("body", node);
31
- const getTagBody = () =>
32
- currentTag.isProgram() ? currentTag : currentTag.get("body");
33
- let { preserveWhitespace } = htmlParseOptions;
34
21
  let currentTag = file.path;
22
+ let currentBody = currentTag;
23
+ let currentAttr = undefined;
24
+ let currentShorthandId = undefined;
25
+ let currentShorthandClassNames = undefined;
26
+ let { preserveWhitespace } = htmlParseOptions;
35
27
  let preservingWhitespaceUntil = preserveWhitespace;
36
- let wasSelfClosing = false;
37
- let handledTagName = false;
38
- let onNext;
39
-
40
- const handlers = {
41
- onDocumentType({ value, pos, endPos }) {
42
- const node = (0, _babelUtils.withLoc)(file, t.markoDocumentType(value), pos, endPos);
43
- pushTagBody(node);
44
- /* istanbul ignore next */
45
- onNext = onNext && onNext(node);
46
- },
28
+ let onNext = noop;
29
+ const positionAt = (index) => toBabelPosition(parser.positionAt(index));
30
+ const locationAt = (range) => {
31
+ // Babel columns start at 0, but that is silly.
32
+ // Here we normalize the parsers 1 based columns.
33
+ const { start, end } = parser.locationAt(range);
34
+ return {
35
+ start: toBabelPosition(start),
36
+ end: toBabelPosition(end) };
37
+
38
+ };
39
+ const withLoc = (node, range) => {
40
+ node.start = range.start;
41
+ node.end = range.end;
42
+ node.loc = locationAt(range);
43
+ return node;
44
+ };
45
+ const enterTag = (node) => {
46
+ currentTag = currentBody.pushContainer("body", node)[0];
47
+ currentBody = currentTag.get("body");
48
+ onNext(node);
49
+ };
50
+ const pushContent = (node) => {
51
+ currentBody.node.body.push(node);
52
+ onNext(node);
53
+ };
54
+ const endAttr = () => {
55
+ if (currentAttr) {
56
+ currentAttr.loc = locationAt(currentAttr);
57
+ currentAttr = undefined;
58
+ }
59
+ };
60
+ const parseTemplateString = ({ quasis, expressions }) => {
61
+ switch (expressions.length) {
62
+ case 0:{
63
+ const [first] = quasis;
64
+ return withLoc(t.stringLiteral(parser.read(first)), first);
65
+ }
66
+ case 1:{
67
+ if (emptyRange(quasis[0]) && emptyRange(quasis[1])) {
68
+ const [{ value }] = expressions;
69
+ const result = (0, _babelUtils.parseExpression)(file, parser.read(value), value.start);
70
+ if (t.isStringLiteral(result)) {
71
+ // convert to template literal just so that we don't mistake it for a native tag if this is a tag name.
72
+ return t.templateLiteral(
73
+ [
74
+ t.templateElement({
75
+ raw: result.value,
76
+ cooked: result.value })],
77
+
78
+
79
+ []);
80
+
81
+ } else {
82
+ return result;
83
+ }
84
+ }
85
+ }}
47
86
 
48
- onDeclaration({ value, pos, endPos }) {
49
- const node = (0, _babelUtils.withLoc)(file, t.markoDeclaration(value), pos, endPos);
50
- pushTagBody(node);
51
- /* istanbul ignore next */
52
- onNext = onNext && onNext(node);
53
- },
54
87
 
55
- onComment({ value, pos, endPos }) {
56
- const node = (0, _babelUtils.withLoc)(file, t.markoComment(value), pos, endPos);
57
- pushTagBody(node);
58
- onNext = onNext && onNext(node);
59
- },
88
+ const [{ start }] = quasis;
89
+ const end = quasis[quasis.length - 1].end;
90
+ return (0, _babelUtils.parseExpression)(
91
+ file,
92
+ `\`${parser.read({ start, end })}\``,
93
+ start - 1);
94
+
95
+ };
60
96
 
61
- onCDATA({ value, pos, endPos }) {
62
- const node = (0, _babelUtils.withLoc)(file, t.markoCDATA(value), pos, endPos);
63
- pushTagBody(node);
64
- onNext = onNext && onNext(node);
97
+ const parser = (0, _htmljsParser.createParser)({
98
+ onError(part) {
99
+ throw file.buildCodeFrameError({ loc: locationAt(part) }, part.message);
65
100
  },
101
+ onText(part) {var _prev;
102
+ const rawValue = parser.read(part);
66
103
 
67
- onText({ value }, parser) {
68
- const shouldTrim = !preservingWhitespaceUntil;
69
- const { body } = getTagBody().node;
70
- let pos = parser.pos - value.length;
104
+ if (preservingWhitespaceUntil) {
105
+ pushContent(withLoc(t.markoText(rawValue), part));
106
+ return;
107
+ }
71
108
 
72
- if (shouldTrim) {
73
- if (htmlTrim(value) === "") {
74
- return;
75
- }
109
+ if (/^(?:[\n\r]\s*)?(?:[\n\r]\s*)?$/.test(rawValue)) return;
76
110
 
77
- // Find previous non-scriptlet/@tag.
78
- let prev;
79
- let prevIndex = body.length;
80
- while (prevIndex > 0) {
81
- prev = body[--prevIndex];
82
-
83
- if (
84
- t.isMarkoClass(prev) ||
85
- t.isMarkoComment(prev) ||
86
- t.isMarkoScriptlet(prev) ||
87
- isAttributeTag(prev))
88
- {
89
- prev = undefined;
90
- } else {
91
- break;
92
- }
93
- }
111
+ const { body } = currentBody.node;
112
+ let prev;
113
+ let prevIndex = body.length;
114
+ // Find previous non-scriptlet or comment.
115
+ while (prevIndex > 0) {
116
+ prev = body[--prevIndex];
94
117
 
95
- if (!prev) {
96
- const originalValue = value;
97
- value = htmlTrimStart(value);
98
- pos += originalValue.indexOf(value);
99
- } else if (
100
- t.isMarkoText(prev) &&
101
- /\s/.test(prev.value[prev.value.length - 1]))
102
- {
103
- const originalValue = value;
104
- value = value.replace(/^\s+/, "");
105
- pos += originalValue.indexOf(value);
118
+ if (t.isMarkoScriptlet(prev) || t.isMarkoComment(prev)) {
119
+ prev = undefined;
120
+ } else {
121
+ break;
106
122
  }
107
123
  }
108
124
 
109
- const endPos = pos + value.length;
110
- const node = (0, _babelUtils.withLoc)(file, t.markoText(value), pos, endPos);
111
- const prevBody = getTagBody().node.body;
112
- pushTagBody(node);
113
- onNext && onNext(node);
114
- onNext =
115
- shouldTrim && (
116
- (next) => {
117
- if (!next || prevBody.indexOf(next) === -1) {
118
- node.value = htmlTrimEnd(node.value);
119
- }
125
+ let value = rawValue;
126
+ switch ((_prev = prev) == null ? void 0 : _prev.type) {
127
+ case "MarkoPlaceholder":
128
+ break;
129
+ case "MarkoText":
130
+ if (/\s$/.test(prev.value)) {
131
+ value = value.replace(/^\s+/, "");
132
+ }
133
+ break;
134
+ case "MarkoTag":
135
+ if (isAttrTag(prev)) {
136
+ value = value.replace(/^[\n\r]\s*/, "");
137
+ }
138
+ break;
139
+ default:
140
+ value = value.replace(/^[\n\r]\s*/, "");
141
+ break;}
142
+
143
+
144
+ const node = t.markoText(value);
145
+ pushContent(node);
146
+ onNext = (next) => {
147
+ switch (next == null ? void 0 : next.type) {
148
+ case "MarkoScriptlet":
149
+ case "MarkoComment":
150
+ return;
151
+ case "MarkoPlaceholder":
152
+ break;
153
+ case "MarkoText":
154
+ if (/^\s/.test(next.value)) {
155
+ value = value.replace(/\s+$/, "");
156
+ }
157
+ break;
158
+ case "MarkoTag":
159
+ if (isAttrTag(next)) {
160
+ value = value.replace(/[\n\r]\s*$/, "");
161
+ }
120
162
 
121
- node.value = node.value.replace(/\s+/g, " ");
122
- });
123
- },
163
+ break;
164
+ default:
165
+ value = value.replace(/[\n\r]\s*$/, "");
166
+ break;}
124
167
 
125
- onPlaceholder({ escape, value, withinBody, pos, endPos }) {
126
- if (withinBody) {
127
- const node = (0, _babelUtils.withLoc)(
128
- file,
129
- t.markoPlaceholder(
130
- (0, _babelUtils.parseExpression)(
131
- file,
132
- value,
133
- pos + (escape ? 2 /* ${ */ : 3) /* $!{ */),
134
168
 
135
- escape),
169
+ node.value = value.replace(/\s+/g, " ");
136
170
 
137
- pos,
138
- endPos);
171
+ if (node.value) {
172
+ const trimmedStart = part.start + rawValue.indexOf(value);
173
+ withLoc(node, {
174
+ start: trimmedStart,
175
+ end: trimmedStart + rawValue.length });
139
176
 
177
+ } else {
178
+ body.splice(body.indexOf(node), 1);
179
+ }
140
180
 
141
- pushTagBody(node);
142
- onNext = onNext && onNext(node);
143
- }
181
+ onNext = noop;
182
+ };
183
+ },
184
+ onCDATA(part) {
185
+ pushContent(withLoc(t.markoCDATA(parser.read(part.value)), part));
186
+ },
187
+ onDoctype(part) {
188
+ pushContent(withLoc(t.markoDocumentType(parser.read(part.value)), part));
189
+ },
190
+ onDeclaration(part) {
191
+ pushContent(withLoc(t.markoDeclaration(parser.read(part.value)), part));
144
192
  },
193
+ onComment(part) {
194
+ pushContent(withLoc(t.markoComment(parser.read(part.value)), part));
195
+ },
196
+ onPlaceholder(part) {
197
+ pushContent(
198
+ withLoc(
199
+ t.markoPlaceholder(
200
+ (0, _babelUtils.parseExpression)(file, parser.read(part.value), part.value.start),
201
+ part.escape),
145
202
 
146
- onScriptlet({ value, line, block, pos, endPos }) {
147
- if (!line && !block) {
148
- throw file.buildCodeFrameError(
149
- { loc: (0, _babelUtils.getLocRange)(file, pos, endPos) },
150
- "<% scriptlets %> are no longer supported.");
203
+ part));
151
204
 
152
- }
153
205
 
154
- pos -= 1; // Include $.
155
- // Scriptlets are ignored as content and don't call `onNext`.
156
- pushTagBody(
157
- (0, _babelUtils.withLoc)(
158
- file,
206
+ },
207
+ onScriptlet(part) {
208
+ pushContent(
209
+ withLoc(
159
210
  t.markoScriptlet(
160
- (0, _babelUtils.parseScript)(file, value, pos + 2 /** Ignores leading `$ ` */).body),
211
+ (0, _babelUtils.parseScript)(file, parser.read(part.value), part.value.start).body),
161
212
 
162
- pos,
163
- endPos));
213
+ part));
164
214
 
165
215
 
166
216
  },
217
+ onTagName(part) {
218
+ const tagName = parseTemplateString(part);
219
+ const node = t.markoTag(tagName, [], t.markoTagBody());
220
+ let parseType = _htmljsParser.TagType.html;
221
+ node.start = part.start - (part.concise ? 0 : 1); // Account for leading `<`.
222
+ node.end = part.end;
167
223
 
168
- onOpenTagName(event) {
169
- const { pos, endPos } = event;
170
- const tagName = event.tagName || "div";
171
- const [, tagNameExpression] =
172
- /^\$\{([\s\S]*)\}/.exec(tagName) || EMPTY_ARRAY;
173
- const tagDef = !tagNameExpression && (0, _babelUtils.getTagDefForTagName)(file, tagName);
174
- const tagNameStartPos = pos + (event.concise ? 0 : 1); // Account for leading `<`.
175
-
176
- handledTagName = true;
177
-
178
- if (tagNameExpression === "") {
179
- throw file.buildCodeFrameError(
180
- { loc: (0, _babelUtils.getLocRange)(file, tagNameStartPos + 1, tagNameStartPos + 3) },
181
- "Missing expression for <${dynamic}> tag.");
224
+ if (t.isStringLiteral(tagName)) {var _node$tagDef;
225
+ const literalTagName = tagName.value || (tagName.value = "div");
182
226
 
183
- }
227
+ if (literalTagName === "%") {
228
+ throw file.buildCodeFrameError(
229
+ tagName,
230
+ "<% scriptlets %> are no longer supported.");
184
231
 
185
- let tagNameNode;
232
+ }
186
233
 
187
- if (tagNameExpression) {
188
- tagNameNode = (0, _babelUtils.parseExpression)(
234
+ const parseOptions = (_node$tagDef = node.tagDef = (0, _babelUtils.getTagDefForTagName)(
189
235
  file,
190
- tagNameExpression,
191
- tagNameStartPos + 2 /* ${ */);
192
-
236
+ literalTagName)) == null ? void 0 : _node$tagDef.
237
+ parseOptions;
193
238
 
194
- if (t.isStringLiteral(tagNameNode)) {
195
- // convert to template literal just so that we don't mistake it for a native tag.
196
- tagNameNode = t.templateLiteral(
197
- [
198
- t.templateElement({
199
- raw: tagNameNode.value,
200
- cooked: tagNameNode.value })],
201
-
202
-
203
- []);
239
+ if (parseOptions) {
240
+ if (parseOptions.preserveWhitespace) {
241
+ preservingWhitespaceUntil = node;
242
+ }
204
243
 
244
+ if (parseOptions.statement) {
245
+ parseType = _htmljsParser.TagType.statement;
246
+ } else if (parseOptions.openTagOnly) {
247
+ parseType = _htmljsParser.TagType.void;
248
+ } else if (parseOptions.text) {
249
+ parseType = _htmljsParser.TagType.text;
250
+ }
205
251
  }
206
- } else {
207
- tagNameNode = (0, _babelUtils.withLoc)(
208
- file,
209
- t.stringLiteral(tagName),
210
- tagNameStartPos,
211
- tagNameStartPos + tagName.length);
252
+ }
212
253
 
254
+ enterTag(node);
255
+ return parseType;
256
+ },
257
+ onTagShorthandId(part) {
258
+ currentShorthandId = parseTemplateString(part);
259
+ },
260
+ onTagShorthandClass(part) {
261
+ if (currentShorthandClassNames) {
262
+ currentShorthandClassNames.push(parseTemplateString(part));
263
+ } else {
264
+ currentShorthandClassNames = [parseTemplateString(part)];
213
265
  }
266
+ },
214
267
 
215
- const node = (0, _babelUtils.withLoc)(
268
+ onTagVar(part) {
269
+ currentTag.node.var = (0, _babelUtils.parseExpression)(
216
270
  file,
217
- t.markoTag(tagNameNode, [], t.markoTagBody()),
218
- pos,
219
- endPos);
271
+ `${parser.read(part.value)}=1`,
272
+ part.value.start).
273
+ left;
274
+ },
220
275
 
276
+ onTagParams(part) {
277
+ currentTag.node.body.params = (0, _babelUtils.parseExpression)(
278
+ file,
279
+ `(${parser.read(part.value)})=>{}`,
280
+ part.start).
281
+ params;
282
+ },
221
283
 
222
- if (tagDef) {
223
- node.tagDef = tagDef;
284
+ onTagArgs(part) {
285
+ currentTag.node.arguments = (0, _babelUtils.parseExpression)(
286
+ file,
287
+ `_${parser.read(part)}`,
288
+ part.start - 1).
289
+ arguments;
290
+ },
224
291
 
225
- const { parseOptions } = tagDef;
226
- if (parseOptions) {
227
- event.setParseOptions(parseOptions);
292
+ onAttrName(part) {
293
+ const [, name, modifier] = /^([^:]*)(?::(.*))?/.exec(parser.read(part));
294
+ endAttr();
295
+ currentTag.node.attributes.push(
296
+ currentAttr = t.markoAttribute(
297
+ name || "default",
298
+ t.booleanLiteral(true),
299
+ modifier,
300
+ undefined,
301
+ !name));
228
302
 
229
- if (parseOptions.rootOnly && !currentTag.isProgram()) {
230
- throw file.buildCodeFrameError(
231
- { loc: (0, _babelUtils.getLocRange)(file, pos, endPos) },
232
- `"${tagName}" tags must be at the root of your Marko template.`);
233
303
 
234
- }
235
- }
236
- }
237
304
 
238
- [currentTag] = pushTagBody(node);
239
-
240
- // @tags are not treated as content and do not call next.
241
- if (!isAttributeTag(node)) {
242
- onNext = onNext && onNext(node);
243
- }
305
+ currentAttr.start = part.start;
306
+ currentAttr.end = part.end;
244
307
  },
245
308
 
246
- onOpenTag(event, parser) {
247
- if (!handledTagName) {
248
- // There is a bug in htmljs parser where a single top level concise mode tag with nothing else
249
- // does not emit the openTagNameEvent.
250
- handlers.onOpenTagName(event);
251
- }
252
-
253
- handledTagName = false;
254
- const { pos, endPos, tagNameEndPos } = event;
255
- const { tagDef } = currentTag.node;
256
- const parseOptions = tagDef && tagDef.parseOptions || EMPTY_OBJECT;
257
- wasSelfClosing = event.selfClosed;
309
+ onAttrArgs(part) {
310
+ currentAttr.arguments = (0, _babelUtils.parseExpression)(
311
+ file,
312
+ `_${parser.read(part)}`,
313
+ part.start - 1).
314
+ arguments;
315
+ currentAttr.end = part.end;
316
+ },
258
317
 
259
- if (parseOptions.state === "parsed-text") {
260
- parser.enterParsedTextContentState();
261
- } else if (parseOptions.state === "static-text") {
262
- parser.enterStaticTextContentState();
263
- }
318
+ onAttrValue(part) {
319
+ currentAttr.end = part.end;
320
+ currentAttr.bound = part.bound;
321
+ currentAttr.value = (0, _babelUtils.parseExpression)(
322
+ file,
323
+ parser.read(part.value),
324
+ part.value.start);
264
325
 
265
- if (parseOptions.rawOpenTag) {
266
- currentTag.set(
267
- "rawValue",
268
- parser.substring(pos, endPos).replace(/^<|\/>$|>$/g, ""));
326
+ },
269
327
 
270
- }
328
+ onAttrMethod(part) {
329
+ const prefix = "function";
330
+ currentAttr.end = part.end;
331
+ currentAttr.value = (0, _babelUtils.parseExpression)(
332
+ file,
333
+ prefix + parser.read(part),
334
+ part.start - prefix.length);
271
335
 
272
- if (!parseOptions.ignoreAttributes) {
273
- currentTag.set("var", (0, _parseVar.default)(file, event.var));
274
- currentTag.get("body").set("params", (0, _parseParams.default)(file, event.params));
275
- currentTag.set("arguments", (0, _parseArguments.default)(file, event.argument));
276
- currentTag.set(
277
- "attributes",
278
- (0, _parseIdShorthand.default)(
279
- file,
280
- event.shorthandId,
281
- (0, _parseClassnameShorthand.default)(
282
- file,
283
- event.shorthandClassNames,
284
- (0, _parseAttributes.default)(file, event.attributes, tagNameEndPos))));
336
+ },
285
337
 
338
+ onAttrSpread(part) {
339
+ endAttr();
340
+ currentTag.node.attributes.push(
341
+ withLoc(
342
+ t.markoSpreadAttribute(
343
+ (0, _babelUtils.parseExpression)(file, parser.read(part.value), part.value.start)),
286
344
 
345
+ part));
287
346
 
288
- }
289
347
 
290
- if (!preservingWhitespaceUntil && parseOptions.preserveWhitespace) {
291
- preservingWhitespaceUntil = currentTag;
292
- }
293
348
  },
294
349
 
295
- onCloseTag(event, parser) {
296
- let { pos, endPos } = event;
297
- const tag = currentTag;
298
- const { node } = tag;
299
- const { tagDef } = node;
300
- const isConcise = code[node.start - 1] !== "<";
350
+ onOpenTagEnd(part) {var _node$tagDef2;
351
+ const { node } = currentTag;
352
+ const { attributes } = node;
353
+ const parseOptions = (_node$tagDef2 = node.tagDef) == null ? void 0 : _node$tagDef2.parseOptions;
354
+ endAttr();
355
+
356
+ if (currentShorthandClassNames) {
357
+ let foundClassAttr = false;
358
+ const classShorthandValue =
359
+ currentShorthandClassNames.length === 1 ?
360
+ currentShorthandClassNames[0] :
361
+ currentShorthandClassNames.every((expr) => t.isStringLiteral(expr)) ?
362
+ withLoc(
363
+ t.stringLiteral(
364
+ currentShorthandClassNames.map((node) => node.value).join(" ")),
301
365
 
302
- if (preservingWhitespaceUntil === currentTag) {
303
- preservingWhitespaceUntil = undefined;
304
- }
366
+ {
367
+ start: currentShorthandClassNames[0].start,
368
+ end: currentShorthandClassNames[
369
+ currentShorthandClassNames.length - 1].
370
+ end }) :
371
+
372
+
373
+ t.arrayExpression(currentShorthandClassNames);
374
+
375
+ for (const attr of attributes) {
376
+ if (attr.name === "class") {
377
+ foundClassAttr = true;
378
+ if (t.isArrayExpression(attr.value)) {
379
+ if (t.isArrayExpression(classShorthandValue)) {
380
+ attr.value.elements.push(...classShorthandValue.elements);
381
+ } else {
382
+ attr.value.elements.push(classShorthandValue);
383
+ }
384
+ } else if (
385
+ t.isStringLiteral(attr.value) &&
386
+ t.isStringLiteral(classShorthandValue))
387
+ {
388
+ attr.value.value = `${classShorthandValue.value} ${attr.value.value}`;
389
+ } else if (t.isArrayExpression(classShorthandValue)) {
390
+ classShorthandValue.elements.push(attr.value);
391
+ attr.value = classShorthandValue;
392
+ } else {
393
+ attr.value = t.arrayExpression([classShorthandValue, attr.value]);
394
+ }
395
+ break;
396
+ }
397
+ }
305
398
 
306
- if (!pos) {
307
- pos = parser.pos;
399
+ if (!foundClassAttr) {
400
+ attributes.push(t.markoAttribute("class", classShorthandValue));
401
+ }
402
+
403
+ currentShorthandClassNames = undefined;
308
404
  }
309
405
 
310
- if (!endPos) {
311
- endPos = pos;
406
+ if (currentShorthandId) {
407
+ for (const attr of attributes) {
408
+ if (attr.name === "id") {
409
+ throw file.buildCodeFrameError(
410
+ attr,
411
+ "Cannot have shorthand id and id attribute.");
312
412
 
313
- if (wasSelfClosing && !isConcise) {
314
- endPos += 2; // account for "/>"
413
+ }
315
414
  }
415
+ currentTag.node.attributes.push(
416
+ t.markoAttribute("id", currentShorthandId));
417
+
418
+ currentShorthandId = undefined;
316
419
  }
317
420
 
318
- node.end = endPos;
319
- node.loc.end = (0, _babelUtils.getLoc)(file, endPos);
421
+ if (parseOptions) {
422
+ if (parseOptions.rawOpenTag) {
423
+ node.rawValue = parser.read({
424
+ start: node.name.start,
425
+ end: part.start });
320
426
 
321
- if (
322
- !isConcise &&
323
- !wasSelfClosing &&
324
- code[pos + 1] !== "/" &&
325
- !currentTag.get("name").isStringLiteral())
326
- {
327
- throw file.buildCodeFrameError(
328
- { loc: (0, _babelUtils.getLocRange)(file, pos, endPos) },
329
- `Invalid ending for dynamic tag, expected "</>".`);
427
+ }
330
428
 
429
+ if (
430
+ part.selfClosed ||
431
+ parseOptions.statement ||
432
+ parseOptions.openTagOnly)
433
+ {
434
+ this.onCloseTag(part);
435
+ }
436
+ } else if (part.selfClosed) {
437
+ this.onCloseTag(part);
438
+ }
439
+ },
440
+ onCloseTag(part) {var _node$tagDef3;
441
+ const { node } = currentTag;
442
+ const parserPlugin = (_node$tagDef3 = node.tagDef) == null ? void 0 : _node$tagDef3.parser;
443
+ if (preservingWhitespaceUntil === node) {
444
+ preservingWhitespaceUntil = undefined;
331
445
  }
332
446
 
333
- if (tagDef && tagDef.parser) {
334
- if (tagDef.parser.path) {
335
- watchFiles.push(tagDef.parser.path);
336
- }
337
- /* istanbul ignore next */
338
- (tagDef.parser.hook.default || tagDef.parser.hook)(tag, t);
447
+ node.end = part.end;
448
+ node.loc = locationAt(node);
449
+
450
+ if (parserPlugin) {
451
+ const { hook } = parserPlugin;
452
+ if (parserPlugin.path) watchFiles.push(parserPlugin.path);
453
+ (hook.default || hook)(currentTag, t);
339
454
  }
340
455
 
341
- currentTag = currentTag.parentPath.parentPath || file.path;
342
- },
456
+ currentTag = currentTag.parentPath.parentPath;
343
457
 
344
- onfinish() {
345
- onNext = onNext && onNext();
346
- },
458
+ if (currentTag) {
459
+ currentBody = currentTag.get("body");
460
+ } else {
461
+ currentTag = currentBody = file.path;
462
+ }
347
463
 
348
- onError({ message, pos, endPos }) {
349
- if (message.includes("EOF")) endPos = pos;
350
- throw file.buildCodeFrameError(
351
- { loc: (0, _babelUtils.getLocRange)(file, pos, endPos) },
352
- message);
464
+ onNext();
465
+ } });
353
466
 
354
- } };
355
467
 
468
+ parser.parse(code);
469
+ onNext();
470
+
471
+ const { ast } = file;
472
+ const { program } = ast;
473
+ ast.start = program.start = 0;
474
+ ast.end = program.end = code.length - 1;
475
+ ast.loc = program.loc = {
476
+ start: { line: 1, column: 0 },
477
+ end: positionAt(ast.end) };
356
478
 
357
- (0, _htmljsParser.createParser)(handlers, {
358
- isOpenTagOnly(name) {
359
- const { parseOptions = EMPTY_OBJECT } =
360
- (0, _babelUtils.getTagDefForTagName)(file, name) || EMPTY_OBJECT;
361
- return parseOptions.openTagOnly;
362
- },
363
- ignoreNonstandardStringPlaceholders: true,
364
- ...htmlParseOptions }).
365
- parse(code, file.opts.filename);
366
479
  }
367
480
  //# sourceMappingURL=parser.js.map