| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 | /** * @author Toru Nagashima * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */'use strict'// ------------------------------------------------------------------------------// Requirements// ------------------------------------------------------------------------------const utils = require('../utils')// ------------------------------------------------------------------------------// Rule Definition// ------------------------------------------------------------------------------module.exports = {  meta: {    docs: {      description: 'enforce valid template root',      category: 'essential',      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.7.1/docs/rules/valid-template-root.md'    },    fixable: null,    schema: []  },  create (context) {    const sourceCode = context.getSourceCode()    return {      Program (program) {        const element = program.templateBody        if (element == null) {          return        }        const hasSrc = utils.hasAttribute(element, 'src')        const rootElements = []        let extraText = null        let extraElement = null        let vIf = false        for (const child of element.children) {          if (child.type === 'VElement') {            if (rootElements.length === 0 && !hasSrc) {              rootElements.push(child)              vIf = utils.hasDirective(child, 'if')            } else if (vIf && utils.hasDirective(child, 'else-if')) {              rootElements.push(child)            } else if (vIf && utils.hasDirective(child, 'else')) {              rootElements.push(child)              vIf = false            } else {              extraElement = child            }          } else if (sourceCode.getText(child).trim() !== '') {            extraText = child          }        }        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,            message: 'The template root requires an element rather than texts.'          })        } else if (extraElement != null) {          context.report({            node: extraElement,            loc: extraElement.loc,            message: 'The template root requires exactly one element.'          })        } else if (rootElements.length === 0 && !hasSrc) {          context.report({            node: element,            loc: element.loc,            message: 'The template root requires exactly one element.'          })        } else {          for (const element of rootElements) {            const tag = element.startTag            const name = element.name            if (name === 'template' || name === 'slot') {              context.report({                node: tag,                loc: tag.loc,                message: "The template root disallows '<{{name}}>' elements.",                data: { name }              })            }            if (utils.hasDirective(element, 'for')) {              context.report({                node: tag,                loc: tag.loc,                message: "The template root disallows 'v-for' directives."              })            }          }        }      }    }  }}
 |