@@ -151,6 +151,7 @@ export class Parser {
151151 private parserOptions : any
152152 private document : VDocumentFragment
153153 private elementStack : VElement [ ]
154+ private vPreElement : VElement | null
154155
155156 /**
156157 * The source code text.
@@ -211,6 +212,13 @@ export class Parser {
211212 return last ( this . elementStack ) || this . document
212213 }
213214
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+
214222 /**
215223 * Initialize this parser.
216224 * @param tokenizer The tokenizer to parse.
@@ -237,6 +245,7 @@ export class Parser {
237245 errors : this . errors ,
238246 }
239247 this . elementStack = [ ]
248+ this . vPreElement = null
240249 }
241250
242251 /**
@@ -277,14 +286,20 @@ export class Parser {
277286 private popElementStack ( ) : void {
278287 assert ( this . elementStack . length >= 1 )
279288
280- const element = this . elementStack . pop ( ) as VElement
289+ const element = this . elementStack . pop ( ) !
281290 propagateEndLocation ( element )
282291
283292 // Update the current namespace.
284293 const current = this . currentNode
285294 this . namespace =
286295 current . type === "VElement" ? current . namespace : NS . HTML
287296
297+ // Update v-pre state.
298+ if ( this . vPreElement === element ) {
299+ this . vPreElement = null
300+ this . expressionEnabled = true
301+ }
302+
288303 // Update expression flag.
289304 if ( this . elementStack . length === 0 ) {
290305 this . expressionEnabled = false
@@ -384,9 +399,11 @@ export class Parser {
384399 const attrName = node . key . name
385400
386401 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" ) )
390407 ) {
391408 convertToDirective (
392409 this . text ,
@@ -442,6 +459,14 @@ export class Parser {
442459 endTag : null ,
443460 variables : [ ] ,
444461 }
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+ }
445470
446471 // Setup relations.
447472 parent . children . push ( element )
@@ -470,11 +495,16 @@ export class Parser {
470495
471496 // Vue.js supports self-closing elements even if it's not one of void elements.
472497 if ( token . selfClosing || isVoid ) {
498+ this . expressionEnabled = ! this . isInVPreElement
473499 return
474500 }
475501
476502 // Push to stack.
477503 this . elementStack . push ( element )
504+ if ( hasVPre ) {
505+ assert ( this . vPreElement === null )
506+ this . vPreElement = element
507+ }
478508 this . namespace = namespace
479509
480510 // Update the content type of this element.
0 commit comments