Browse Source

ignore text nodes between v-if conditions (fix #4533)

Evan You 9 years ago
parent
commit
de220a635d
2 changed files with 31 additions and 7 deletions
  1. 17 7
      src/compiler/parser/index.js
  2. 14 0
      test/unit/modules/compiler/parser.spec.js

+ 17 - 7
src/compiler/parser/index.js

@@ -352,6 +352,23 @@ function processIfConditions (el, parent) {
   }
 }
 
+function findPrevElement (children: Array<any>): ASTElement | void {
+  let i = children.length
+  while (i--) {
+    if (children[i].type === 1) {
+      return children[i]
+    } else {
+      if (process.env.NODE_ENV !== 'production' && children[i].text !== ' ') {
+        warn(
+          `text "${children[i].text.trim()}" between v-if and v-else(-if) ` +
+          `will be ignored.`
+        )
+      }
+      children.pop()
+    }
+  }
+}
+
 function addIfCondition (el, condition) {
   if (!el.ifConditions) {
     el.ifConditions = []
@@ -503,13 +520,6 @@ function makeAttrsMap (attrs: Array<Object>): Object {
   return map
 }
 
-function findPrevElement (children: Array<any>): ASTElement | void {
-  let i = children.length
-  while (i--) {
-    if (children[i].tag) return children[i]
-  }
-}
-
 function isForbiddenTag (el): boolean {
   return (
     el.tag === 'style' ||

+ 14 - 0
test/unit/modules/compiler/parser.spec.js

@@ -82,6 +82,20 @@ describe('parser', () => {
     expect('Component template should contain exactly one root element:\n\n<div></div><div></div>').toHaveBeenWarned()
   })
 
+  it('remove text nodes between v-if conditions', () => {
+    const ast = parse(`<div><div v-if="1"></div> <div v-else-if="2"></div> <div v-else></div> <span></span></div>`, baseOptions)
+    expect(ast.children.length).toBe(3)
+    expect(ast.children[0].tag).toBe('div')
+    expect(ast.children[0].ifConditions.length).toBe(3)
+    expect(ast.children[1].text).toBe(' ') // text
+    expect(ast.children[2].tag).toBe('span')
+  })
+
+  it('warn non whitespace text between v-if conditions', () => {
+    parse(`<div><div v-if="1"></div> foo <div v-else></div></div>`, baseOptions)
+    expect(`text "foo" between v-if and v-else(-if) will be ignored`).toHaveBeenWarned()
+  })
+
   it('not warn 2 root elements with v-if and v-else', () => {
     parse('<div v-if="1"></div><div v-else></div>', baseOptions)
     expect('Component template should contain exactly one root element')