Skip to content

Fix: no-invalid-template-root has false positive about empty templates (fixes #41) #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/rules/no-confusing-v-for-v-if.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ So when they exist on the same node, `v-if` directive should use the reference w

## 📖 Rule Details

This rule reports the elements which have both `v-for` and `v-if` directives if the following cases:
This rule reports the elements which have both `v-for` and `v-if` directives in the following cases:

- The `v-if` directive does not use the reference which is to the variables which are defined by the `v-for` directives.

Expand Down
17 changes: 11 additions & 6 deletions docs/rules/no-invalid-template-root.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,21 @@ This rule checks whether every template root is valid.

## 📖 Rule Details

This rule reports the template root if the following cases:
This rule reports the template root in the following cases:

- The root is nothing. E.g. `<template></template>`.
- The root is text. E.g. `<template>hello</template>`.
- The root is multiple elements. E.g. `<template><div>one</div><div>two</div></template>`.
- The root element has `v-for` directives. E.g. `<template><div v-for="x in list">{{x}}</div></template>`.
- The root element has `v-if`/`v-else-if` directives without `v-else` elements. E.g. `<template><div v-if="foo">hello</div></template>`.
- The root element is `<template>` or `<slot>` elements. E.g. `<template><template>hello</template></template>`.

👎 Examples of **incorrect** code for this rule:

```html
<template>
</template>
```

```html
<template>
<div>hello</div>
Expand All @@ -33,17 +38,17 @@ This rule reports the template root if the following cases:
</template>
```

👍 Examples of **correct** code for this rule:

```html
<template>
<div v-if="foo"></div>
<div>abc</div>
</template>
```

👍 Examples of **correct** code for this rule:

```html
<template>
<div>abc</div>
<div v-if="foo"></div>
</template>
```

Expand Down
2 changes: 1 addition & 1 deletion docs/rules/no-invalid-v-bind.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This rule checks whether every `v-bind` directive is valid.

## 📖 Rule Details

This rule reports `v-bind` directives if the following cases:
This rule reports `v-bind` directives in the following cases:

- The directive does not have that attribute value. E.g. `<div v-bind:aaa></div>`
- The directive has invalid modifiers. E.g. `<div v-bind:aaa.bbb="ccc"></div>`
Expand Down
2 changes: 1 addition & 1 deletion docs/rules/no-invalid-v-cloak.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This rule checks whether every `v-cloak` directive is valid.

## 📖 Rule Details

This rule reports `v-cloak` directives if the following cases:
This rule reports `v-cloak` directives in the following cases:

- The directive has that argument. E.g. `<div v-cloak:aaa></div>`
- The directive has that modifier. E.g. `<div v-cloak.bbb></div>`
Expand Down
2 changes: 1 addition & 1 deletion docs/rules/no-invalid-v-else-if.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This rule checks whether every `v-else-if` directive is valid.

## 📖 Rule Details

This rule reports `v-else-if` directives if the following cases:
This rule reports `v-else-if` directives in the following cases:

- The directive has that argument. E.g. `<div v-if="foo"></div><div v-else-if:aaa="bar"></div>`
- The directive has that modifier. E.g. `<div v-if="foo"></div><div v-else-if.bbb="bar"></div>`
Expand Down
2 changes: 1 addition & 1 deletion docs/rules/no-invalid-v-else.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This rule checks whether every `v-else` directive is valid.

## 📖 Rule Details

This rule reports `v-else` directives if the following cases:
This rule reports `v-else` directives in the following cases:

- The directive has that argument. E.g. `<div v-if="foo"></div><div v-else:aaa></div>`
- The directive has that modifier. E.g. `<div v-if="foo"></div><div v-else.bbb></div>`
Expand Down
2 changes: 1 addition & 1 deletion docs/rules/no-invalid-v-for.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This rule checks whether every `v-for` directive is valid.

## 📖 Rule Details

This rule reports `v-for` directives if the following cases:
This rule reports `v-for` directives in the following cases:

- The directive has that argument. E.g. `<div v-for:aaa></div>`
- The directive has that modifier. E.g. `<div v-for.bbb></div>`
Expand Down
2 changes: 1 addition & 1 deletion docs/rules/no-invalid-v-html.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This rule checks whether every `v-html` directive is valid.

## 📖 Rule Details

This rule reports `v-html` directives if the following cases:
This rule reports `v-html` directives in the following cases:

- The directive has that argument. E.g. `<div v-html:aaa></div>`
- The directive has that modifier. E.g. `<div v-html.bbb></div>`
Expand Down
2 changes: 1 addition & 1 deletion docs/rules/no-invalid-v-if.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This rule checks whether every `v-if` directive is valid.

## 📖 Rule Details

This rule reports `v-if` directives if the following cases:
This rule reports `v-if` directives in the following cases:

- The directive has that argument. E.g. `<div v-if:aaa="foo"></div>`
- The directive has that modifier. E.g. `<div v-if.bbb="foo"></div>`
Expand Down
2 changes: 1 addition & 1 deletion docs/rules/no-invalid-v-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This rule checks whether every `v-model` directive is valid.

## 📖 Rule Details

This rule reports `v-model` directives if the following cases:
This rule reports `v-model` directives in the following cases:

- The directive has that argument. E.g. `<input v-model:aaa="foo">`
- The directive has the modifiers which are not supported. E.g. `<input v-model.bbb="foo">`
Expand Down
2 changes: 1 addition & 1 deletion docs/rules/no-invalid-v-on.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This rule checks whether every `v-on` directive is valid.

## 📖 Rule Details

This rule reports `v-on` directives if the following cases:
This rule reports `v-on` directives in the following cases:

- The directive does not have that event name. E.g. `<div v-on="foo"></div>`
- The directive has invalid modifiers. E.g. `<div v-on:click.bbb="foo"></div>`
Expand Down
2 changes: 1 addition & 1 deletion docs/rules/no-invalid-v-once.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This rule checks whether every `v-once` directive is valid.

## 📖 Rule Details

This rule reports `v-once` directives if the following cases:
This rule reports `v-once` directives in the following cases:

- The directive has that argument. E.g. `<div v-once:aaa></div>`
- The directive has that modifier. E.g. `<div v-once.bbb></div>`
Expand Down
2 changes: 1 addition & 1 deletion docs/rules/no-invalid-v-pre.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This rule checks whether every `v-pre` directive is valid.

## 📖 Rule Details

This rule reports `v-pre` directives if the following cases:
This rule reports `v-pre` directives in the following cases:

- The directive has that argument. E.g. `<div v-pre:aaa></div>`
- The directive has that modifier. E.g. `<div v-pre.bbb></div>`
Expand Down
2 changes: 1 addition & 1 deletion docs/rules/no-invalid-v-show.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This rule checks whether every `v-show` directive is valid.

## 📖 Rule Details

This rule reports `v-show` directives if the following cases:
This rule reports `v-show` directives in the following cases:

- The directive has that argument. E.g. `<div v-show:aaa></div>`
- The directive has that modifier. E.g. `<div v-show.bbb></div>`
Expand Down
2 changes: 1 addition & 1 deletion docs/rules/no-invalid-v-text.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This rule checks whether every `v-text` directive is valid.

## 📖 Rule Details

This rule reports `v-text` directives if the following cases:
This rule reports `v-text` directives in the following cases:

- The directive has that argument. E.g. `<div v-text:aaa></div>`
- The directive has that modifier. E.g. `<div v-text.bbb></div>`
Expand Down
21 changes: 10 additions & 11 deletions lib/rules/no-invalid-template-root.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ function create (context) {
return
}

const hasSrc = utils.hasAttribute(node.startTag, 'src')
const rootElements = []
let extraText = null
let extraElement = null
let vIf = false
for (const child of node.children) {
if (child.type === 'VElement') {
if (rootElements.length === 0) {
if (rootElements.length === 0 && !hasSrc) {
rootElements.push(child)
vIf = utils.hasDirective(child.startTag, 'if')
} else if (vIf && utils.hasDirective(child.startTag, 'else-if')) {
Expand All @@ -53,7 +54,13 @@ function create (context) {
}
}

if (extraText != null) {
if (hasSrc && (extraText != null || extraElement != null)) {
context.report({
node: extraText || extraElement,
loc: (extraText || extraElement).loc,
message: "The template root with 'src' attribute is required to be empty."
})
} else if (extraText != null) {
context.report({
node: extraText,
loc: extraText.loc,
Expand All @@ -65,7 +72,7 @@ function create (context) {
loc: extraElement.loc,
message: 'The template root requires exactly one element.'
})
} else if (rootElements.length === 0) {
} else if (rootElements.length === 0 && !hasSrc) {
context.report({
node,
loc: node.loc,
Expand All @@ -92,14 +99,6 @@ function create (context) {
})
}
}
if (vIf) {
const tag = rootElements[0].startTag
context.report({
node: tag,
loc: tag.loc,
message: "The template root requires the next element which has 'v-else' directives if it has 'v-if' directives."
})
}
}
}
}
Expand Down
28 changes: 20 additions & 8 deletions tests/lib/rules/no-invalid-template-root.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ tester.run('no-invalid-template-root', rule, {
{
filename: 'test.vue',
code: `<template>\n <c1 v-if="1" />\n <c2 v-else-if="1" />\n <c3 v-else />\n</template>`
},
{
filename: 'test.vue',
code: '<template><div v-if="foo"></div></template>'
},
{
filename: 'test.vue',
code: '<template><div v-if="foo"></div><div v-else-if="bar"></div></template>'
},
{
filename: 'test.vue',
code: '<template src="foo.html"></template>'
}
],
invalid: [
Expand Down Expand Up @@ -90,23 +102,23 @@ tester.run('no-invalid-template-root', rule, {
},
{
filename: 'test.vue',
code: '<template><div v-if="foo"></div></template>',
errors: ["The template root requires the next element which has 'v-else' directives if it has 'v-if' directives."]
code: '<template><slot></slot></template>',
errors: ["The template root disallows '<slot>' elements."]
},
{
filename: 'test.vue',
code: '<template><div v-if="foo"></div><div v-else-if="bar"></div></template>',
errors: ["The template root requires the next element which has 'v-else' directives if it has 'v-if' directives."]
code: '<template><template></template></template>',
errors: ["The template root disallows '<template>' elements."]
},
{
filename: 'test.vue',
code: '<template><slot></slot></template>',
errors: ["The template root disallows '<slot>' elements."]
code: '<template src="foo.html">abc</template>',
errors: ["The template root with 'src' attribute is required to be empty."]
},
{
filename: 'test.vue',
code: '<template><template></template></template>',
errors: ["The template root disallows '<template>' elements."]
code: '<template src="foo.html"><div></div></template>',
errors: ["The template root with 'src' attribute is required to be empty."]
}
]
})