Skip to content

Commit

Permalink
🐛 disable expressions in v-pre elements (vuejs/eslint-plugin-vue#733)
Browse files Browse the repository at this point in the history
  • Loading branch information
mysticatea committed Jan 4, 2019
1 parent 7113191 commit 31425ae
Show file tree
Hide file tree
Showing 5 changed files with 1,476 additions and 4 deletions.
38 changes: 34 additions & 4 deletions src/html/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export class Parser {
private parserOptions: any
private document: VDocumentFragment
private elementStack: VElement[]
private vPreElement: VElement | null

/**
* The source code text.
Expand Down Expand Up @@ -211,6 +212,13 @@ export class Parser {
return last(this.elementStack) || this.document
}

/**
* Check if the current location is in a v-pre element.
*/
private get isInVPreElement(): boolean {
return this.vPreElement != null
}

/**
* Initialize this parser.
* @param tokenizer The tokenizer to parse.
Expand All @@ -237,6 +245,7 @@ export class Parser {
errors: this.errors,
}
this.elementStack = []
this.vPreElement = null
}

/**
Expand Down Expand Up @@ -277,14 +286,20 @@ export class Parser {
private popElementStack(): void {
assert(this.elementStack.length >= 1)

const element = this.elementStack.pop() as VElement
const element = this.elementStack.pop()!
propagateEndLocation(element)

// Update the current namespace.
const current = this.currentNode
this.namespace =
current.type === "VElement" ? current.namespace : NS.HTML

// Update v-pre state.
if (this.vPreElement === element) {
this.vPreElement = null
this.expressionEnabled = true
}

// Update expression flag.
if (this.elementStack.length === 0) {
this.expressionEnabled = false
Expand Down Expand Up @@ -384,9 +399,11 @@ export class Parser {
const attrName = node.key.name

if (
DIRECTIVE_NAME.test(attrName) ||
attrName === "slot-scope" ||
(tagName === "template" && attrName === "scope")
(this.expressionEnabled ||
(attrName === "v-pre" && !this.isInVPreElement)) &&
(DIRECTIVE_NAME.test(attrName) ||
attrName === "slot-scope" ||
(tagName === "template" && attrName === "scope"))
) {
convertToDirective(
this.text,
Expand Down Expand Up @@ -442,6 +459,14 @@ export class Parser {
endTag: null,
variables: [],
}
const hasVPre =
!this.isInVPreElement &&
token.attributes.some(a => a.key.name === "v-pre")

// Disable expression if v-pre
if (hasVPre) {
this.expressionEnabled = false
}

// Setup relations.
parent.children.push(element)
Expand Down Expand Up @@ -470,11 +495,16 @@ export class Parser {

// Vue.js supports self-closing elements even if it's not one of void elements.
if (token.selfClosing || isVoid) {
this.expressionEnabled = !this.isInVPreElement
return
}

// Push to stack.
this.elementStack.push(element)
if (hasVPre) {
assert(this.vPreElement === null)
this.vPreElement = element
}
this.namespace = namespace

// Update the content type of this element.
Expand Down
Loading

0 comments on commit 31425ae

Please sign in to comment.