eslint-plugin-mpx 0.0.21 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/README.md +3 -0
  2. package/lib/.DS_Store +0 -0
  3. package/lib/configs/base.js +10 -5
  4. package/lib/configs/mpx-essential.js +0 -30
  5. package/lib/index.js +1 -150
  6. package/lib/rules/comment-directive.js +2 -2
  7. package/lib/rules/component-tags-order.js +2 -2
  8. package/lib/rules/eqeqeq.js +4 -2
  9. package/lib/rules/html-end-tags.js +1 -1
  10. package/lib/rules/no-arrow-functions-in-watch.js +2 -2
  11. package/lib/rules/no-async-in-computed-properties.js +5 -5
  12. package/lib/rules/no-dupe-keys.js +3 -3
  13. package/lib/rules/no-dupe-wx-elif.js +8 -3
  14. package/lib/rules/no-duplicate-attributes.js +6 -16
  15. package/lib/rules/no-parsing-error.js +2 -2
  16. package/lib/rules/no-reserved-keys.js +3 -3
  17. package/lib/rules/no-side-effects-in-computed-properties.js +8 -9
  18. package/lib/rules/return-in-computed-property.js +3 -3
  19. package/lib/rules/syntaxes/dynamic-directive-arguments.js +2 -1
  20. package/lib/rules/syntaxes/scope-attribute.js +2 -1
  21. package/lib/rules/syntaxes/slot-attribute.js +2 -1
  22. package/lib/rules/syntaxes/v-bind-prop-modifier-shorthand.js +2 -1
  23. package/lib/rules/valid-wx-elif.js +1 -1
  24. package/lib/rules/valid-wx-else.js +1 -1
  25. package/lib/rules/valid-wx-for.js +2 -2
  26. package/lib/rules/valid-wx-if.js +1 -1
  27. package/lib/rules/valid-wx-model.js +2 -2
  28. package/lib/utils/index.js +504 -490
  29. package/lib/utils/keycode-to-key.js +60 -60
  30. package/lib/utils/{vue-reserved.json → mpx-reserved.json} +2 -2
  31. package/package.json +18 -15
  32. package/lib/configs/essential.js +0 -51
  33. package/lib/configs/no-layout-rules.js +0 -47
  34. package/lib/configs/recommended.js +0 -17
  35. package/lib/configs/strongly-recommended.js +0 -32
  36. package/lib/configs/vue3-essential.js +0 -71
  37. package/lib/configs/vue3-recommended.js +0 -17
  38. package/lib/configs/vue3-strongly-recommended.js +0 -33
  39. package/lib/rules/array-bracket-spacing.js +0 -12
  40. package/lib/rules/arrow-spacing.js +0 -9
  41. package/lib/rules/attribute-hyphenation.js +0 -121
  42. package/lib/rules/attributes-order.js +0 -281
  43. package/lib/rules/block-spacing.js +0 -11
  44. package/lib/rules/brace-style.js +0 -11
  45. package/lib/rules/camelcase.js +0 -9
  46. package/lib/rules/comma-dangle.js +0 -9
  47. package/lib/rules/comma-spacing.js +0 -12
  48. package/lib/rules/comma-style.js +0 -20
  49. package/lib/rules/component-definition-name-casing.js +0 -108
  50. package/lib/rules/component-name-in-template-casing.js +0 -164
  51. package/lib/rules/custom-event-name-casing.js +0 -214
  52. package/lib/rules/dot-location.js +0 -9
  53. package/lib/rules/dot-notation.js +0 -9
  54. package/lib/rules/func-call-spacing.js +0 -11
  55. package/lib/rules/html-closing-bracket-newline.js +0 -115
  56. package/lib/rules/html-closing-bracket-spacing.js +0 -137
  57. package/lib/rules/html-comment-content-newline.js +0 -215
  58. package/lib/rules/html-comment-content-spacing.js +0 -179
  59. package/lib/rules/html-comment-indent.js +0 -258
  60. package/lib/rules/html-indent.js +0 -81
  61. package/lib/rules/html-quotes.js +0 -107
  62. package/lib/rules/html-self-closing.js +0 -222
  63. package/lib/rules/jsx-uses-vars.js +0 -73
  64. package/lib/rules/key-spacing.js +0 -11
  65. package/lib/rules/keyword-spacing.js +0 -11
  66. package/lib/rules/match-component-file-name.js +0 -151
  67. package/lib/rules/max-attributes-per-line.js +0 -194
  68. package/lib/rules/max-len.js +0 -561
  69. package/lib/rules/multiline-html-element-content-newline.js +0 -246
  70. package/lib/rules/mustache-interpolation-spacing.js +0 -107
  71. package/lib/rules/name-property-casing.js +0 -71
  72. package/lib/rules/no-bare-strings-in-template.js +0 -275
  73. package/lib/rules/no-boolean-default.js +0 -114
  74. package/lib/rules/no-confusing-v-for-v-if.js +0 -69
  75. package/lib/rules/no-custom-modifiers-on-v-model.js +0 -59
  76. package/lib/rules/no-deprecated-data-object-declaration.js +0 -95
  77. package/lib/rules/no-deprecated-destroyed-lifecycle.js +0 -101
  78. package/lib/rules/no-deprecated-dollar-listeners-api.js +0 -72
  79. package/lib/rules/no-deprecated-dollar-scopedslots-api.js +0 -79
  80. package/lib/rules/no-deprecated-events-api.js +0 -69
  81. package/lib/rules/no-deprecated-filter.js +0 -44
  82. package/lib/rules/no-deprecated-functional-template.js +0 -56
  83. package/lib/rules/no-deprecated-html-element-is.js +0 -54
  84. package/lib/rules/no-deprecated-inline-template.js +0 -47
  85. package/lib/rules/no-deprecated-scope-attribute.js +0 -31
  86. package/lib/rules/no-deprecated-slot-attribute.js +0 -29
  87. package/lib/rules/no-deprecated-slot-scope-attribute.js +0 -34
  88. package/lib/rules/no-deprecated-v-bind-sync.js +0 -62
  89. package/lib/rules/no-deprecated-v-on-native-modifier.js +0 -50
  90. package/lib/rules/no-deprecated-v-on-number-modifiers.js +0 -61
  91. package/lib/rules/no-deprecated-vue-config-keycodes.js +0 -53
  92. package/lib/rules/no-duplicate-attr-inheritance.js +0 -67
  93. package/lib/rules/no-empty-component-block.js +0 -109
  94. package/lib/rules/no-empty-pattern.js +0 -9
  95. package/lib/rules/no-extra-parens.js +0 -182
  96. package/lib/rules/no-irregular-whitespace.js +0 -251
  97. package/lib/rules/no-lifecycle-after-await.js +0 -133
  98. package/lib/rules/no-lone-template.js +0 -129
  99. package/lib/rules/no-multi-spaces.js +0 -107
  100. package/lib/rules/no-multiple-objects-in-class.js +0 -59
  101. package/lib/rules/no-multiple-slot-args.js +0 -118
  102. package/lib/rules/no-multiple-template-root.js +0 -101
  103. package/lib/rules/no-mutating-props.js +0 -323
  104. package/lib/rules/no-potential-component-option-typo.js +0 -125
  105. package/lib/rules/no-ref-as-operand.js +0 -189
  106. package/lib/rules/no-reserved-component-names.js +0 -187
  107. package/lib/rules/no-restricted-component-options.js +0 -215
  108. package/lib/rules/no-restricted-static-attribute.js +0 -164
  109. package/lib/rules/no-restricted-syntax.js +0 -9
  110. package/lib/rules/no-restricted-v-bind.js +0 -184
  111. package/lib/rules/no-setup-props-destructure.js +0 -149
  112. package/lib/rules/no-spaces-around-equal-signs-in-attribute.js +0 -57
  113. package/lib/rules/no-sparse-arrays.js +0 -9
  114. package/lib/rules/no-static-inline-styles.js +0 -141
  115. package/lib/rules/no-template-key.js +0 -48
  116. package/lib/rules/no-template-shadow.js +0 -101
  117. package/lib/rules/no-template-target-blank.js +0 -138
  118. package/lib/rules/no-textarea-mustache.js +0 -46
  119. package/lib/rules/no-unregistered-components.js +0 -187
  120. package/lib/rules/no-unsupported-features.js +0 -157
  121. package/lib/rules/no-unused-components.js +0 -143
  122. package/lib/rules/no-unused-properties.js +0 -742
  123. package/lib/rules/no-unused-vars.js +0 -147
  124. package/lib/rules/no-use-v-if-with-v-for.js +0 -119
  125. package/lib/rules/no-useless-concat.js +0 -9
  126. package/lib/rules/no-useless-mustaches.js +0 -154
  127. package/lib/rules/no-useless-v-bind.js +0 -150
  128. package/lib/rules/no-v-html.js +0 -36
  129. package/lib/rules/no-v-model-argument.js +0 -49
  130. package/lib/rules/no-watch-after-await.js +0 -142
  131. package/lib/rules/object-curly-newline.js +0 -12
  132. package/lib/rules/object-curly-spacing.js +0 -12
  133. package/lib/rules/object-property-newline.js +0 -12
  134. package/lib/rules/one-component-per-file.js +0 -50
  135. package/lib/rules/operator-linebreak.js +0 -9
  136. package/lib/rules/order-in-components.js +0 -341
  137. package/lib/rules/padding-line-between-blocks.js +0 -220
  138. package/lib/rules/prefer-template.js +0 -9
  139. package/lib/rules/prop-name-casing.js +0 -66
  140. package/lib/rules/require-component-is.js +0 -45
  141. package/lib/rules/require-default-prop.js +0 -190
  142. package/lib/rules/require-direct-export.js +0 -128
  143. package/lib/rules/require-explicit-emits.js +0 -511
  144. package/lib/rules/require-name-property.js +0 -43
  145. package/lib/rules/require-prop-type-constructor.js +0 -99
  146. package/lib/rules/require-prop-types.js +0 -103
  147. package/lib/rules/require-render-return.js +0 -50
  148. package/lib/rules/require-slots-as-functions.js +0 -120
  149. package/lib/rules/require-toggle-inside-transition.js +0 -89
  150. package/lib/rules/require-v-for-key.js +0 -62
  151. package/lib/rules/require-valid-default-prop.js +0 -338
  152. package/lib/rules/return-in-emits-validator.js +0 -141
  153. package/lib/rules/script-indent.js +0 -56
  154. package/lib/rules/singleline-html-element-content-newline.js +0 -215
  155. package/lib/rules/sort-keys.js +0 -282
  156. package/lib/rules/space-in-parens.js +0 -12
  157. package/lib/rules/space-infix-ops.js +0 -11
  158. package/lib/rules/space-unary-ops.js +0 -11
  159. package/lib/rules/static-class-names-order.js +0 -61
  160. package/lib/rules/template-curly-spacing.js +0 -12
  161. package/lib/rules/this-in-template.js +0 -128
  162. package/lib/rules/use-v-on-exact.js +0 -228
  163. package/lib/rules/v-bind-style.js +0 -76
  164. package/lib/rules/v-for-delimiter-style.js +0 -69
  165. package/lib/rules/v-on-function-call.js +0 -172
  166. package/lib/rules/v-on-style.js +0 -58
  167. package/lib/rules/v-slot-style.js +0 -155
  168. package/lib/rules/valid-template-root.js +0 -69
  169. package/lib/rules/valid-v-bind-sync.js +0 -179
  170. package/lib/rules/valid-v-bind.js +0 -62
  171. package/lib/rules/valid-v-cloak.js +0 -58
  172. package/lib/rules/valid-v-html.js +0 -58
  173. package/lib/rules/valid-v-is.js +0 -95
  174. package/lib/rules/valid-v-on.js +0 -153
  175. package/lib/rules/valid-v-once.js +0 -58
  176. package/lib/rules/valid-v-pre.js +0 -58
  177. package/lib/rules/valid-v-show.js +0 -58
  178. package/lib/rules/valid-v-slot.js +0 -290
  179. package/lib/rules/valid-v-text.js +0 -58
  180. package/lib/utils/indent-common.js +0 -2085
@@ -1,129 +0,0 @@
1
- /**
2
- * @author Yosuke Ota
3
- * See LICENSE file in root directory for full license.
4
- */
5
- 'use strict'
6
-
7
- // ------------------------------------------------------------------------------
8
- // Requirements
9
- // ------------------------------------------------------------------------------
10
-
11
- const utils = require('../utils')
12
-
13
- // ------------------------------------------------------------------------------
14
- // Helpers
15
- // ------------------------------------------------------------------------------
16
-
17
- // https://github.com/vuejs/vue-next/blob/64e2f4643602c5980361e66674141e61ba60ef70/packages/compiler-core/src/parse.ts#L405
18
- const SPECIAL_TEMPLATE_DIRECTIVES = new Set([
19
- 'if',
20
- 'else',
21
- 'else-if',
22
- 'for',
23
- 'slot'
24
- ])
25
-
26
- // ------------------------------------------------------------------------------
27
- // Rule Definition
28
- // ------------------------------------------------------------------------------
29
-
30
- module.exports = {
31
- meta: {
32
- type: 'problem',
33
- docs: {
34
- description: 'disallow unnecessary `<template>`',
35
- categories: ['vue3-recommended', 'recommended'],
36
- url: 'https://eslint.vuejs.org/rules/no-lone-template.html'
37
- },
38
- fixable: null,
39
- schema: [
40
- {
41
- type: 'object',
42
- properties: {
43
- ignoreAccessible: {
44
- type: 'boolean'
45
- }
46
- },
47
- additionalProperties: false
48
- }
49
- ],
50
- messages: {
51
- requireDirective: '`<template>` require directive.'
52
- }
53
- },
54
- /** @param {RuleContext} context */
55
- create(context) {
56
- const options = context.options[0] || {}
57
- const ignoreAccessible = options.ignoreAccessible === true
58
-
59
- /**
60
- * @param {VAttribute | VDirective} attr
61
- */
62
- function getKeyName(attr) {
63
- if (attr.directive) {
64
- if (attr.key.name.name !== 'bind') {
65
- // no v-bind
66
- return null
67
- }
68
- if (
69
- !attr.key.argument ||
70
- attr.key.argument.type === 'VExpressionContainer'
71
- ) {
72
- // unknown
73
- return null
74
- }
75
- return attr.key.argument.name
76
- }
77
- return attr.key.name
78
- }
79
-
80
- return utils.defineTemplateBodyVisitor(context, {
81
- /** @param {VStartTag} node */
82
- "VElement[name='template'][parent.type='VElement'] > VStartTag"(node) {
83
- if (
84
- node.attributes.some((attr) => {
85
- if (attr.directive) {
86
- const directiveName = attr.key.name.name
87
- if (SPECIAL_TEMPLATE_DIRECTIVES.has(directiveName)) {
88
- return true
89
- }
90
- if (directiveName === 'slot-scope') {
91
- // `slot-scope` is deprecated in Vue.js 2.6
92
- return true
93
- }
94
- if (directiveName === 'scope') {
95
- // `scope` is deprecated in Vue.js 2.5
96
- return true
97
- }
98
- }
99
-
100
- const keyName = getKeyName(attr)
101
- if (keyName === 'slot') {
102
- // `slot` is deprecated in Vue.js 2.6
103
- return true
104
- }
105
-
106
- return false
107
- })
108
- ) {
109
- return
110
- }
111
-
112
- if (
113
- ignoreAccessible &&
114
- node.attributes.some((attr) => {
115
- const keyName = getKeyName(attr)
116
- return keyName === 'id' || keyName === 'ref'
117
- })
118
- ) {
119
- return
120
- }
121
-
122
- context.report({
123
- node,
124
- messageId: 'requireDirective'
125
- })
126
- }
127
- })
128
- }
129
- }
@@ -1,107 +0,0 @@
1
- /**
2
- * @fileoverview This rule warns about the usage of extra whitespaces between attributes
3
- * @author Armano
4
- */
5
- 'use strict'
6
-
7
- const path = require('path')
8
-
9
- // ------------------------------------------------------------------------------
10
- // Rule Definition
11
- // ------------------------------------------------------------------------------
12
-
13
- /**
14
- * @param {RuleContext} context
15
- * @param {Token} node
16
- */
17
- const isProperty = (context, node) => {
18
- const sourceCode = context.getSourceCode()
19
- return node.type === 'Punctuator' && sourceCode.getText(node) === ':'
20
- }
21
-
22
- module.exports = {
23
- meta: {
24
- type: 'layout',
25
- docs: {
26
- description: 'disallow multiple spaces',
27
- categories: ['vue3-strongly-recommended', 'strongly-recommended'],
28
- url: 'https://eslint.vuejs.org/rules/no-multi-spaces.html'
29
- },
30
- fixable: 'whitespace', // or "code" or "whitespace"
31
- schema: [
32
- {
33
- type: 'object',
34
- properties: {
35
- ignoreProperties: {
36
- type: 'boolean'
37
- }
38
- },
39
- additionalProperties: false
40
- }
41
- ]
42
- },
43
-
44
- /**
45
- * @param {RuleContext} context - The rule context.
46
- * @returns {RuleListener} AST event handlers.
47
- */
48
- create(context) {
49
- const options = context.options[0] || {}
50
- const ignoreProperties = options.ignoreProperties === true
51
-
52
- return {
53
- Program(node) {
54
- if (context.parserServices.getTemplateBodyTokenStore == null) {
55
- const filename = context.getFilename()
56
- if (path.extname(filename) === '.mpx') {
57
- context.report({
58
- loc: { line: 1, column: 0 },
59
- message:
60
- 'Use the latest vue-eslint-parser. See also https://eslint.vuejs.org/user-guide/#what-is-the-use-the-latest-vue-eslint-parser-error.'
61
- })
62
- }
63
- return
64
- }
65
- if (!node.templateBody) {
66
- return
67
- }
68
- const sourceCode = context.getSourceCode()
69
- const tokenStore = context.parserServices.getTemplateBodyTokenStore()
70
- const tokens = tokenStore.getTokens(node.templateBody, {
71
- includeComments: true
72
- })
73
-
74
- let prevToken = /** @type {Token} */ (tokens.shift())
75
- for (const token of tokens) {
76
- const spaces = token.range[0] - prevToken.range[1]
77
- const shouldIgnore =
78
- ignoreProperties &&
79
- (isProperty(context, token) || isProperty(context, prevToken))
80
- if (
81
- spaces > 1 &&
82
- token.loc.start.line === prevToken.loc.start.line &&
83
- !shouldIgnore
84
- ) {
85
- context.report({
86
- node: token,
87
- loc: {
88
- start: prevToken.loc.end,
89
- end: token.loc.start
90
- },
91
- message: "Multiple spaces found before '{{displayValue}}'.",
92
- fix: (fixer) =>
93
- fixer.replaceTextRange(
94
- [prevToken.range[1], token.range[0]],
95
- ' '
96
- ),
97
- data: {
98
- displayValue: sourceCode.getText(token)
99
- }
100
- })
101
- }
102
- prevToken = token
103
- }
104
- }
105
- }
106
- }
107
- }
@@ -1,59 +0,0 @@
1
- /**
2
- * @author tyankatsu <https://github.com/tyankatsu0105>
3
- * See LICENSE file in root directory for full license.
4
- */
5
- 'use strict'
6
-
7
- // ------------------------------------------------------------------------------
8
- // Requirements
9
- // ------------------------------------------------------------------------------
10
-
11
- const { defineTemplateBodyVisitor } = require('../utils')
12
-
13
- // ------------------------------------------------------------------------------
14
- // Rule Definition
15
- // ------------------------------------------------------------------------------
16
-
17
- /**
18
- * count ObjectExpression element
19
- * @param {VDirective & {value: VExpressionContainer & {expression: ArrayExpression}}} node
20
- * @return {number}
21
- */
22
- function countObjectExpression(node) {
23
- return node.value.expression.elements.filter(
24
- (element) => element && element.type === 'ObjectExpression'
25
- ).length
26
- }
27
-
28
- module.exports = {
29
- meta: {
30
- type: 'suggestion',
31
- docs: {
32
- description: 'disallow to pass multiple objects into array to class',
33
- categories: undefined,
34
- url: 'https://eslint.vuejs.org/rules/no-multiple-objects-in-class.html'
35
- },
36
- fixable: null,
37
- schema: [],
38
- messages: {
39
- unexpected: 'Unexpected multiple objects. Merge objects.'
40
- }
41
- },
42
- /** @param {RuleContext} context */
43
- create(context) {
44
- return defineTemplateBodyVisitor(context, {
45
- /** @param {VDirective & {value: VExpressionContainer & {expression: ArrayExpression}}} node */
46
- 'VAttribute[directive=true][key.argument.name="class"][key.name.name="bind"][value.expression.type="ArrayExpression"]'(
47
- node
48
- ) {
49
- if (countObjectExpression(node) > 1) {
50
- context.report({
51
- node,
52
- loc: node.loc,
53
- messageId: 'unexpected'
54
- })
55
- }
56
- }
57
- })
58
- }
59
- }
@@ -1,118 +0,0 @@
1
- /**
2
- * @author Yosuke Ota
3
- * See LICENSE file in root directory for full license.
4
- */
5
- 'use strict'
6
-
7
- // ------------------------------------------------------------------------------
8
- // Requirements
9
- // ------------------------------------------------------------------------------
10
-
11
- const utils = require('../utils')
12
- const { findVariable } = require('eslint-utils')
13
-
14
- // ------------------------------------------------------------------------------
15
- // Rule Definition
16
- // ------------------------------------------------------------------------------
17
-
18
- module.exports = {
19
- meta: {
20
- type: 'problem',
21
- docs: {
22
- description: 'disallow to pass multiple arguments to scoped slots',
23
- categories: ['vue3-recommended', 'recommended'],
24
- url: 'https://eslint.vuejs.org/rules/no-multiple-slot-args.html'
25
- },
26
- fixable: null,
27
- schema: [],
28
- messages: {
29
- unexpected: 'Unexpected multiple arguments.',
30
- unexpectedSpread: 'Unexpected spread argument.'
31
- }
32
- },
33
- /** @param {RuleContext} context */
34
- create(context) {
35
- /**
36
- * Verify the given node
37
- * @param {MemberExpression | Identifier} node The node to verify
38
- */
39
- function verify(node) {
40
- const parent = node.parent
41
-
42
- if (
43
- parent.type === 'VariableDeclarator' &&
44
- parent.id.type === 'Identifier'
45
- ) {
46
- // const foo = this.$scopedSlots.foo
47
- verifyReferences(parent.id)
48
- return
49
- }
50
-
51
- if (
52
- parent.type === 'AssignmentExpression' &&
53
- parent.right === node &&
54
- parent.left.type === 'Identifier'
55
- ) {
56
- // foo = this.$scopedSlots.foo
57
- verifyReferences(parent.left)
58
- return
59
- }
60
-
61
- if (parent.type !== 'CallExpression' || parent.arguments.includes(node)) {
62
- return
63
- }
64
-
65
- if (!parent.arguments.length) {
66
- return
67
- }
68
- if (parent.arguments.length > 1) {
69
- context.report({
70
- node: parent.arguments[1],
71
- messageId: 'unexpected'
72
- })
73
- }
74
- if (parent.arguments[0].type === 'SpreadElement') {
75
- context.report({
76
- node: parent.arguments[0],
77
- messageId: 'unexpectedSpread'
78
- })
79
- }
80
- }
81
- /**
82
- * Verify the references of the given node.
83
- * @param {Identifier} node The node to verify
84
- */
85
- function verifyReferences(node) {
86
- const variable = findVariable(context.getScope(), node)
87
- if (!variable) {
88
- return
89
- }
90
- for (const reference of variable.references) {
91
- if (!reference.isRead()) {
92
- continue
93
- }
94
- /** @type {Identifier} */
95
- const id = reference.identifier
96
- verify(id)
97
- }
98
- }
99
-
100
- return utils.defineVueVisitor(context, {
101
- /** @param {MemberExpression} node */
102
- MemberExpression(node) {
103
- const object = utils.skipChainExpression(node.object)
104
- if (object.type !== 'MemberExpression') {
105
- return
106
- }
107
- const name = utils.getStaticPropertyName(object)
108
- if (!name || (name !== '$slots' && name !== '$scopedSlots')) {
109
- return
110
- }
111
- if (!utils.isThis(object.object, context)) {
112
- return
113
- }
114
- verify(node)
115
- }
116
- })
117
- }
118
- }
@@ -1,101 +0,0 @@
1
- /**
2
- * @fileoverview disallow adding multiple root nodes to the template
3
- * @author Przemyslaw Falowski (@przemkow)
4
- */
5
- 'use strict'
6
-
7
- // ------------------------------------------------------------------------------
8
- // Requirements
9
- // ------------------------------------------------------------------------------
10
-
11
- const utils = require('../utils')
12
-
13
- // ------------------------------------------------------------------------------
14
- // Rule Definition
15
- // ------------------------------------------------------------------------------
16
-
17
- module.exports = {
18
- meta: {
19
- type: 'problem',
20
- docs: {
21
- description: 'disallow adding multiple root nodes to the template',
22
- categories: ['essential'],
23
- url: 'https://eslint.vuejs.org/rules/no-multiple-template-root.html'
24
- },
25
- fixable: null,
26
- schema: []
27
- },
28
- /**
29
- * @param {RuleContext} context - The rule context.
30
- * @returns {RuleListener} AST event handlers.
31
- */
32
- create(context) {
33
- const sourceCode = context.getSourceCode()
34
-
35
- return {
36
- Program(program) {
37
- const element = program.templateBody
38
- if (element == null) {
39
- return
40
- }
41
-
42
- const rootElements = []
43
- let extraText = null
44
- let extraElement = null
45
- let vIf = false
46
- for (const child of element.children) {
47
- if (child.type === 'VElement') {
48
- if (rootElements.length === 0) {
49
- rootElements.push(child)
50
- vIf = utils.hasDirective(child, 'if')
51
- } else if (vIf && utils.hasDirective(child, 'else-if')) {
52
- rootElements.push(child)
53
- } else if (vIf && utils.hasDirective(child, 'else')) {
54
- rootElements.push(child)
55
- vIf = false
56
- } else {
57
- extraElement = child
58
- }
59
- } else if (sourceCode.getText(child).trim() !== '') {
60
- extraText = child
61
- }
62
- }
63
-
64
- if (extraText != null) {
65
- context.report({
66
- node: extraText,
67
- loc: extraText.loc,
68
- message: 'The template root requires an element rather than texts.'
69
- })
70
- } else if (extraElement != null) {
71
- context.report({
72
- node: extraElement,
73
- loc: extraElement.loc,
74
- message: 'The template root requires exactly one element.'
75
- })
76
- } else {
77
- for (const element of rootElements) {
78
- const tag = element.startTag
79
- const name = element.name
80
-
81
- if (name === 'template' || name === 'slot') {
82
- context.report({
83
- node: tag,
84
- loc: tag.loc,
85
- message: "The template root disallows '<{{name}}>' elements.",
86
- data: { name }
87
- })
88
- }
89
- if (utils.hasDirective(element, 'for')) {
90
- context.report({
91
- node: tag,
92
- loc: tag.loc,
93
- message: "The template root disallows 'v-for' directives."
94
- })
95
- }
96
- }
97
- }
98
- }
99
- }
100
- }
101
- }