@@ -151,6 +151,7 @@ export class Parser {
151
151
private parserOptions : any
152
152
private document : VDocumentFragment
153
153
private elementStack : VElement [ ]
154
+ private vPreElement : VElement | null
154
155
155
156
/**
156
157
* The source code text.
@@ -211,6 +212,13 @@ export class Parser {
211
212
return last ( this . elementStack ) || this . document
212
213
}
213
214
215
+ /**
216
+ * Check if the current location is in a v-pre element.
217
+ */
218
+ private get isInVPreElement ( ) : boolean {
219
+ return this . vPreElement != null
220
+ }
221
+
214
222
/**
215
223
* Initialize this parser.
216
224
* @param tokenizer The tokenizer to parse.
@@ -237,6 +245,7 @@ export class Parser {
237
245
errors : this . errors ,
238
246
}
239
247
this . elementStack = [ ]
248
+ this . vPreElement = null
240
249
}
241
250
242
251
/**
@@ -277,14 +286,20 @@ export class Parser {
277
286
private popElementStack ( ) : void {
278
287
assert ( this . elementStack . length >= 1 )
279
288
280
- const element = this . elementStack . pop ( ) as VElement
289
+ const element = this . elementStack . pop ( ) !
281
290
propagateEndLocation ( element )
282
291
283
292
// Update the current namespace.
284
293
const current = this . currentNode
285
294
this . namespace =
286
295
current . type === "VElement" ? current . namespace : NS . HTML
287
296
297
+ // Update v-pre state.
298
+ if ( this . vPreElement === element ) {
299
+ this . vPreElement = null
300
+ this . expressionEnabled = true
301
+ }
302
+
288
303
// Update expression flag.
289
304
if ( this . elementStack . length === 0 ) {
290
305
this . expressionEnabled = false
@@ -384,9 +399,11 @@ export class Parser {
384
399
const attrName = node . key . name
385
400
386
401
if (
387
- DIRECTIVE_NAME . test ( attrName ) ||
388
- attrName === "slot-scope" ||
389
- ( tagName === "template" && attrName === "scope" )
402
+ ( this . expressionEnabled ||
403
+ ( attrName === "v-pre" && ! this . isInVPreElement ) ) &&
404
+ ( DIRECTIVE_NAME . test ( attrName ) ||
405
+ attrName === "slot-scope" ||
406
+ ( tagName === "template" && attrName === "scope" ) )
390
407
) {
391
408
convertToDirective (
392
409
this . text ,
@@ -442,6 +459,14 @@ export class Parser {
442
459
endTag : null ,
443
460
variables : [ ] ,
444
461
}
462
+ const hasVPre =
463
+ ! this . isInVPreElement &&
464
+ token . attributes . some ( a => a . key . name === "v-pre" )
465
+
466
+ // Disable expression if v-pre
467
+ if ( hasVPre ) {
468
+ this . expressionEnabled = false
469
+ }
445
470
446
471
// Setup relations.
447
472
parent . children . push ( element )
@@ -470,11 +495,16 @@ export class Parser {
470
495
471
496
// Vue.js supports self-closing elements even if it's not one of void elements.
472
497
if ( token . selfClosing || isVoid ) {
498
+ this . expressionEnabled = ! this . isInVPreElement
473
499
return
474
500
}
475
501
476
502
// Push to stack.
477
503
this . elementStack . push ( element )
504
+ if ( hasVPre ) {
505
+ assert ( this . vPreElement === null )
506
+ this . vPreElement = element
507
+ }
478
508
this . namespace = namespace
479
509
480
510
// Update the content type of this element.
0 commit comments