@html-eslint/eslint-plugin 0.35.0-alpha.0 → 0.35.1
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.
- package/lib/rules/attrs-newline.js +11 -7
- package/lib/rules/element-newline.js +172 -160
- package/lib/rules/id-naming-convention.js +10 -4
- package/lib/rules/indent/indent-level.js +1 -1
- package/lib/rules/indent/indent.js +28 -15
- package/lib/rules/lowercase.js +4 -4
- package/lib/rules/max-element-depth.js +8 -5
- package/lib/rules/no-abstract-roles.js +4 -4
- package/lib/rules/no-accesskey-attrs.js +4 -4
- package/lib/rules/no-aria-hidden-body.js +1 -1
- package/lib/rules/no-duplicate-attrs.js +4 -4
- package/lib/rules/no-duplicate-id.js +5 -5
- package/lib/rules/no-extra-spacing-attrs.js +18 -12
- package/lib/rules/no-extra-spacing-text.js +8 -5
- package/lib/rules/no-heading-inside-button.js +1 -1
- package/lib/rules/no-inline-styles.js +1 -1
- package/lib/rules/no-invalid-role.js +1 -1
- package/lib/rules/no-multiple-empty-lines.js +8 -5
- package/lib/rules/no-multiple-h1.js +2 -2
- package/lib/rules/no-nested-interactive.js +2 -2
- package/lib/rules/no-non-scalable-viewport.js +1 -1
- package/lib/rules/no-obsolete-tags.js +1 -1
- package/lib/rules/no-positive-tabindex.js +4 -4
- package/lib/rules/no-restricted-attr-values.js +5 -5
- package/lib/rules/no-restricted-attrs.js +8 -7
- package/lib/rules/no-script-style-type.js +4 -4
- package/lib/rules/no-skip-heading-levels.js +2 -2
- package/lib/rules/no-target-blank.js +1 -1
- package/lib/rules/no-trailing-spaces.js +3 -3
- package/lib/rules/prefer-https.js +5 -5
- package/lib/rules/quotes.js +7 -5
- package/lib/rules/require-attrs.js +7 -5
- package/lib/rules/require-button-type.js +1 -1
- package/lib/rules/require-closing-tags.js +6 -2
- package/lib/rules/require-doctype.js +1 -1
- package/lib/rules/require-explicit-size.js +8 -3
- package/lib/rules/require-form-method.js +1 -1
- package/lib/rules/require-frame-title.js +1 -1
- package/lib/rules/require-img-alt.js +9 -8
- package/lib/rules/require-input-label.js +2 -2
- package/lib/rules/require-lang.js +4 -7
- package/lib/rules/require-li-container.js +1 -1
- package/lib/rules/require-meta-charset.js +3 -3
- package/lib/rules/require-meta-description.js +3 -3
- package/lib/rules/require-meta-viewport.js +3 -3
- package/lib/rules/require-open-graph-protocol.js +6 -3
- package/lib/rules/require-title.js +4 -4
- package/lib/rules/sort-attrs.js +11 -11
- package/lib/rules/utils/node.js +31 -19
- package/lib/rules/utils/settings.js +3 -3
- package/lib/rules/utils/source-code.js +1 -1
- package/lib/rules/utils/visitors.js +1 -1
- package/lib/types/ast.d.ts +4 -194
- package/lib/types/index.d.ts +1 -1
- package/lib/types/rule.d.ts +41 -10
- package/package.json +11 -20
- package/types/configs/recommended.d.ts +0 -20
- package/types/configs/recommended.d.ts.map +0 -1
- package/types/constants/index.d.ts +0 -5
- package/types/constants/index.d.ts.map +0 -1
- package/types/constants/obsolete-tags.d.ts +0 -3
- package/types/constants/obsolete-tags.d.ts.map +0 -1
- package/types/constants/rule-category.d.ts +0 -5
- package/types/constants/rule-category.d.ts.map +0 -1
- package/types/constants/svg-camel-case-attributes.d.ts +0 -3
- package/types/constants/svg-camel-case-attributes.d.ts.map +0 -1
- package/types/constants/void-elements.d.ts +0 -3
- package/types/constants/void-elements.d.ts.map +0 -1
- package/types/index.d.ts +0 -14
- package/types/index.d.ts.map +0 -1
- package/types/rules/attrs-newline.d.ts +0 -13
- package/types/rules/attrs-newline.d.ts.map +0 -1
- package/types/rules/element-newline.d.ts +0 -19
- package/types/rules/element-newline.d.ts.map +0 -1
- package/types/rules/id-naming-convention.d.ts +0 -10
- package/types/rules/id-naming-convention.d.ts.map +0 -1
- package/types/rules/indent/indent-level.d.ts +0 -55
- package/types/rules/indent/indent-level.d.ts.map +0 -1
- package/types/rules/indent/indent.d.ts +0 -30
- package/types/rules/indent/indent.d.ts.map +0 -1
- package/types/rules/indent/index.d.ts +0 -3
- package/types/rules/indent/index.d.ts.map +0 -1
- package/types/rules/index.d.ts +0 -51
- package/types/rules/index.d.ts.map +0 -1
- package/types/rules/lowercase.d.ts +0 -10
- package/types/rules/lowercase.d.ts.map +0 -1
- package/types/rules/max-element-depth.d.ts +0 -10
- package/types/rules/max-element-depth.d.ts.map +0 -1
- package/types/rules/no-abstract-roles.d.ts +0 -10
- package/types/rules/no-abstract-roles.d.ts.map +0 -1
- package/types/rules/no-accesskey-attrs.d.ts +0 -10
- package/types/rules/no-accesskey-attrs.d.ts.map +0 -1
- package/types/rules/no-aria-hidden-body.d.ts +0 -7
- package/types/rules/no-aria-hidden-body.d.ts.map +0 -1
- package/types/rules/no-duplicate-attrs.d.ts +0 -10
- package/types/rules/no-duplicate-attrs.d.ts.map +0 -1
- package/types/rules/no-duplicate-id.d.ts +0 -11
- package/types/rules/no-duplicate-id.d.ts.map +0 -1
- package/types/rules/no-extra-spacing-attrs.d.ts +0 -18
- package/types/rules/no-extra-spacing-attrs.d.ts.map +0 -1
- package/types/rules/no-extra-spacing-text.d.ts +0 -13
- package/types/rules/no-extra-spacing-text.d.ts.map +0 -1
- package/types/rules/no-heading-inside-button.d.ts +0 -7
- package/types/rules/no-heading-inside-button.d.ts.map +0 -1
- package/types/rules/no-inline-styles.d.ts +0 -7
- package/types/rules/no-inline-styles.d.ts.map +0 -1
- package/types/rules/no-invalid-role.d.ts +0 -7
- package/types/rules/no-invalid-role.d.ts.map +0 -1
- package/types/rules/no-multiple-empty-lines.d.ts +0 -11
- package/types/rules/no-multiple-empty-lines.d.ts.map +0 -1
- package/types/rules/no-multiple-h1.d.ts +0 -8
- package/types/rules/no-multiple-h1.d.ts.map +0 -1
- package/types/rules/no-nested-interactive.d.ts +0 -8
- package/types/rules/no-nested-interactive.d.ts.map +0 -1
- package/types/rules/no-non-scalable-viewport.d.ts +0 -7
- package/types/rules/no-non-scalable-viewport.d.ts.map +0 -1
- package/types/rules/no-obsolete-tags.d.ts +0 -7
- package/types/rules/no-obsolete-tags.d.ts.map +0 -1
- package/types/rules/no-positive-tabindex.d.ts +0 -10
- package/types/rules/no-positive-tabindex.d.ts.map +0 -1
- package/types/rules/no-restricted-attr-values.d.ts +0 -16
- package/types/rules/no-restricted-attr-values.d.ts.map +0 -1
- package/types/rules/no-restricted-attrs.d.ts +0 -16
- package/types/rules/no-restricted-attrs.d.ts.map +0 -1
- package/types/rules/no-script-style-type.d.ts +0 -10
- package/types/rules/no-script-style-type.d.ts.map +0 -1
- package/types/rules/no-skip-heading-levels.d.ts +0 -8
- package/types/rules/no-skip-heading-levels.d.ts.map +0 -1
- package/types/rules/no-target-blank.d.ts +0 -7
- package/types/rules/no-target-blank.d.ts.map +0 -1
- package/types/rules/no-trailing-spaces.d.ts +0 -9
- package/types/rules/no-trailing-spaces.d.ts.map +0 -1
- package/types/rules/prefer-https.d.ts +0 -11
- package/types/rules/prefer-https.d.ts.map +0 -1
- package/types/rules/quotes.d.ts +0 -12
- package/types/rules/quotes.d.ts.map +0 -1
- package/types/rules/require-attrs.d.ts +0 -15
- package/types/rules/require-attrs.d.ts.map +0 -1
- package/types/rules/require-button-type.d.ts +0 -7
- package/types/rules/require-button-type.d.ts.map +0 -1
- package/types/rules/require-closing-tags.d.ts +0 -8
- package/types/rules/require-closing-tags.d.ts.map +0 -1
- package/types/rules/require-doctype.d.ts +0 -7
- package/types/rules/require-doctype.d.ts.map +0 -1
- package/types/rules/require-explicit-size.d.ts +0 -9
- package/types/rules/require-explicit-size.d.ts.map +0 -1
- package/types/rules/require-form-method.d.ts +0 -7
- package/types/rules/require-form-method.d.ts.map +0 -1
- package/types/rules/require-frame-title.d.ts +0 -7
- package/types/rules/require-frame-title.d.ts.map +0 -1
- package/types/rules/require-img-alt.d.ts +0 -8
- package/types/rules/require-img-alt.d.ts.map +0 -1
- package/types/rules/require-input-label.d.ts +0 -8
- package/types/rules/require-input-label.d.ts.map +0 -1
- package/types/rules/require-lang.d.ts +0 -7
- package/types/rules/require-lang.d.ts.map +0 -1
- package/types/rules/require-li-container.d.ts +0 -7
- package/types/rules/require-li-container.d.ts.map +0 -1
- package/types/rules/require-meta-charset.d.ts +0 -9
- package/types/rules/require-meta-charset.d.ts.map +0 -1
- package/types/rules/require-meta-description.d.ts +0 -9
- package/types/rules/require-meta-description.d.ts.map +0 -1
- package/types/rules/require-meta-viewport.d.ts +0 -9
- package/types/rules/require-meta-viewport.d.ts.map +0 -1
- package/types/rules/require-open-graph-protocol.d.ts +0 -9
- package/types/rules/require-open-graph-protocol.d.ts.map +0 -1
- package/types/rules/require-title.d.ts +0 -10
- package/types/rules/require-title.d.ts.map +0 -1
- package/types/rules/sort-attrs.d.ts +0 -10
- package/types/rules/sort-attrs.d.ts.map +0 -1
- package/types/rules/utils/array.d.ts +0 -17
- package/types/rules/utils/array.d.ts.map +0 -1
- package/types/rules/utils/naming.d.ts +0 -25
- package/types/rules/utils/naming.d.ts.map +0 -1
- package/types/rules/utils/node.d.ts +0 -111
- package/types/rules/utils/node.d.ts.map +0 -1
- package/types/rules/utils/settings.d.ts +0 -19
- package/types/rules/utils/settings.d.ts.map +0 -1
- package/types/rules/utils/source-code.d.ts +0 -9
- package/types/rules/utils/source-code.d.ts.map +0 -1
- package/types/rules/utils/visitors.d.ts +0 -10
- package/types/rules/utils/visitors.d.ts.map +0 -1
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef { import("
|
|
3
|
-
* @typedef { import("../types").RuleModule } RuleModule
|
|
2
|
+
* @typedef { import("../types").RuleFixer } RuleFixer
|
|
4
3
|
*
|
|
5
|
-
* @typedef {Object
|
|
4
|
+
* @typedef {Object} MessageId
|
|
6
5
|
* @property {"closeStyleWrong"} CLOSE_STYLE_WRONG
|
|
7
6
|
* @property {"newlineMissing"} NEWLINE_MISSING
|
|
8
7
|
* @property {"newlineUnexpected"} NEWLINE_UNEXPECTED
|
|
8
|
+
*
|
|
9
|
+
* @typedef {Object} Option
|
|
10
|
+
* @property {"sameline" | "newline"} [option.closeStyle]
|
|
11
|
+
* @property {number} [options.ifAttrsMoreThan]
|
|
12
|
+
*
|
|
13
|
+
* @typedef { import("../types").RuleModule<[Option]> } RuleModule
|
|
9
14
|
*/
|
|
10
15
|
|
|
11
16
|
const { RULE_CATEGORY } = require("../constants");
|
|
@@ -58,9 +63,8 @@ module.exports = {
|
|
|
58
63
|
|
|
59
64
|
create(context) {
|
|
60
65
|
const options = context.options[0] || {};
|
|
61
|
-
const attrMin =
|
|
62
|
-
? 2
|
|
63
|
-
: options.ifAttrsMoreThan;
|
|
66
|
+
const attrMin =
|
|
67
|
+
typeof options.ifAttrsMoreThan !== "number" ? 2 : options.ifAttrsMoreThan;
|
|
64
68
|
const closeStyle = options.closeStyle || "newline";
|
|
65
69
|
|
|
66
70
|
return createVisitors(context, {
|
|
@@ -147,7 +151,7 @@ module.exports = {
|
|
|
147
151
|
return context.report({
|
|
148
152
|
node,
|
|
149
153
|
data: {
|
|
150
|
-
attrMin
|
|
154
|
+
attrMin: `${attrMin}`,
|
|
151
155
|
},
|
|
152
156
|
fix,
|
|
153
157
|
messageId: MESSAGE_ID.NEWLINE_UNEXPECTED,
|
|
@@ -1,27 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef { import("
|
|
3
|
-
* @typedef { import("
|
|
4
|
-
* @typedef { import("
|
|
5
|
-
* @typedef { import("
|
|
6
|
-
* @typedef { import("
|
|
7
|
-
* @typedef { import("
|
|
8
|
-
* @typedef { import("
|
|
9
|
-
* @typedef {
|
|
10
|
-
* @typedef {
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* }
|
|
2
|
+
* @typedef { import("@html-eslint/types").Tag } Tag
|
|
3
|
+
* @typedef { import("@html-eslint/types").Comment } Comment
|
|
4
|
+
* @typedef { import("@html-eslint/types").Doctype } Doctype
|
|
5
|
+
* @typedef { import("@html-eslint/types").ScriptTag } ScriptTag
|
|
6
|
+
* @typedef { import("@html-eslint/types").StyleTag } StyleTag
|
|
7
|
+
* @typedef { import("@html-eslint/types").Text } Text
|
|
8
|
+
* @typedef { import("@html-eslint/types").AnyNode } AnyNode
|
|
9
|
+
* @typedef { import("@html-eslint/types").OpenTagEnd } OpenTagEnd
|
|
10
|
+
* @typedef { import("@html-eslint/types").CloseTag } CloseTag
|
|
11
|
+
* @typedef { import("../types").Line } Line
|
|
12
|
+
* @typedef { AnyNode | Line } AnyNodeOrLine
|
|
13
|
+
*
|
|
14
|
+
* @typedef {Object} Option
|
|
15
|
+
* @property {string[]} [Option.skip]
|
|
16
|
+
* @property {string[]} [Option.inline]
|
|
17
|
+
*
|
|
18
|
+
* @typedef { import("../types").RuleModule<[Option]> } RuleModule
|
|
15
19
|
*/
|
|
16
20
|
|
|
17
21
|
const { RULE_CATEGORY } = require("../constants");
|
|
18
|
-
const {
|
|
22
|
+
const {
|
|
23
|
+
isTag,
|
|
24
|
+
isComment,
|
|
25
|
+
isText,
|
|
26
|
+
splitToLineNodes,
|
|
27
|
+
isLine,
|
|
28
|
+
isScript,
|
|
29
|
+
isStyle,
|
|
30
|
+
} = require("./utils/node");
|
|
19
31
|
const { createVisitors } = require("./utils/visitors");
|
|
20
32
|
const MESSAGE_IDS = {
|
|
21
33
|
EXPECT_NEW_LINE_AFTER: "expectAfter",
|
|
22
|
-
EXPECT_NEW_LINE_AFTER_OPEN: "expectAfterOpen",
|
|
23
|
-
EXPECT_NEW_LINE_BEFORE: "expectBefore",
|
|
24
|
-
EXPECT_NEW_LINE_BEFORE_CLOSE: "expectBeforeClose",
|
|
25
34
|
};
|
|
26
35
|
|
|
27
36
|
/**
|
|
@@ -100,167 +109,169 @@ module.exports = {
|
|
|
100
109
|
],
|
|
101
110
|
messages: {
|
|
102
111
|
[MESSAGE_IDS.EXPECT_NEW_LINE_AFTER]:
|
|
103
|
-
"There should be a linebreak after {{
|
|
104
|
-
[MESSAGE_IDS.EXPECT_NEW_LINE_AFTER_OPEN]:
|
|
105
|
-
"There should be a linebreak after {{tag}} open.",
|
|
106
|
-
[MESSAGE_IDS.EXPECT_NEW_LINE_BEFORE]:
|
|
107
|
-
"There should be a linebreak before {{tag}} element.",
|
|
108
|
-
[MESSAGE_IDS.EXPECT_NEW_LINE_BEFORE_CLOSE]:
|
|
109
|
-
"There should be a linebreak before {{tag}} close.",
|
|
112
|
+
"There should be a linebreak after {{name}}.",
|
|
110
113
|
},
|
|
111
114
|
},
|
|
112
115
|
|
|
113
116
|
create(context) {
|
|
114
117
|
const option = context.options[0] || {};
|
|
115
|
-
|
|
118
|
+
/**
|
|
119
|
+
* @type {string[]}
|
|
120
|
+
*/
|
|
121
|
+
const skipTags = option.skip || ["pre", "code"];
|
|
116
122
|
const inlineTags = optionsOrPresets(option.inline || []);
|
|
117
123
|
|
|
118
124
|
/**
|
|
119
|
-
* @param {
|
|
120
|
-
* @returns {
|
|
125
|
+
* @param {AnyNodeOrLine[]} children
|
|
126
|
+
* @returns {Exclude<AnyNodeOrLine, Text>[]}
|
|
121
127
|
*/
|
|
122
|
-
function
|
|
128
|
+
function getChildrenToCheck(children) {
|
|
123
129
|
/**
|
|
124
|
-
* @type {
|
|
130
|
+
* @type {Exclude<AnyNodeOrLine, Text>[]}
|
|
125
131
|
*/
|
|
126
|
-
const
|
|
127
|
-
childFirst: null,
|
|
128
|
-
childLast: null,
|
|
129
|
-
shouldBeNewline: false,
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
const nodesWithContent = [];
|
|
133
|
-
for (
|
|
134
|
-
let length = siblings.length, index = 0;
|
|
135
|
-
index < length;
|
|
136
|
-
index += 1
|
|
137
|
-
) {
|
|
138
|
-
const node = siblings[index];
|
|
132
|
+
const childrenToCheck = [];
|
|
139
133
|
|
|
140
|
-
|
|
141
|
-
|
|
134
|
+
for (const child of children) {
|
|
135
|
+
if (isText(child)) {
|
|
136
|
+
const lines = splitToLineNodes(child);
|
|
137
|
+
childrenToCheck.push(...lines);
|
|
138
|
+
continue;
|
|
142
139
|
}
|
|
140
|
+
childrenToCheck.push(child);
|
|
143
141
|
}
|
|
142
|
+
return childrenToCheck.filter((child) => !isEmptyText(child));
|
|
143
|
+
}
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
145
|
+
/**
|
|
146
|
+
* @param {AnyNodeOrLine} before
|
|
147
|
+
* @param {AnyNodeOrLine} after
|
|
148
|
+
* @returns {boolean}
|
|
149
|
+
*/
|
|
150
|
+
function isOnTheSameLine(before, after) {
|
|
151
|
+
return before.loc.end.line === after.loc.start.line;
|
|
152
|
+
}
|
|
152
153
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
/**
|
|
155
|
+
* @param {AnyNode} node
|
|
156
|
+
* @returns {boolean}
|
|
157
|
+
*/
|
|
158
|
+
function shouldSkipChildren(node) {
|
|
159
|
+
if (isTag(node) && skipTags.includes(node.name.toLowerCase())) {
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
156
164
|
|
|
157
|
-
|
|
165
|
+
/**
|
|
166
|
+
* @param {AnyNodeOrLine} node
|
|
167
|
+
* @returns {boolean}
|
|
168
|
+
*/
|
|
169
|
+
function isInline(node) {
|
|
170
|
+
return (
|
|
171
|
+
isLine(node) ||
|
|
172
|
+
(isTag(node) && inlineTags.includes(node.name.toLowerCase()))
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* @param {AnyNode[]} children
|
|
178
|
+
* @param {AnyNode} parent
|
|
179
|
+
* @param {[OpenTagEnd, CloseTag]} [wrapper]
|
|
180
|
+
*/
|
|
181
|
+
function checkChildren(children, parent, wrapper) {
|
|
182
|
+
if (shouldSkipChildren(parent)) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
158
185
|
|
|
159
|
-
|
|
186
|
+
const childrenToCheck = getChildrenToCheck(children);
|
|
187
|
+
const firstChild = childrenToCheck[0];
|
|
188
|
+
if (
|
|
189
|
+
wrapper &&
|
|
190
|
+
firstChild &&
|
|
191
|
+
childrenToCheck.some((child) => !isInline(child))
|
|
192
|
+
) {
|
|
193
|
+
const open = wrapper[0];
|
|
194
|
+
if (isOnTheSameLine(open, firstChild)) {
|
|
195
|
+
context.report({
|
|
196
|
+
node: open,
|
|
197
|
+
messageId: MESSAGE_IDS.EXPECT_NEW_LINE_AFTER,
|
|
198
|
+
data: { name: getName(parent) },
|
|
199
|
+
fix(fixer) {
|
|
200
|
+
return fixer.insertTextAfter(open, `\n`);
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
160
205
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const nodeChildShouldBeNewline = nodeMeta.shouldBeNewline;
|
|
206
|
+
childrenToCheck.forEach((current, index) => {
|
|
207
|
+
const next = childrenToCheck[index + 1];
|
|
164
208
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
209
|
+
if (
|
|
210
|
+
!next ||
|
|
211
|
+
!isOnTheSameLine(current, next) ||
|
|
212
|
+
(isInline(current) && isInline(next))
|
|
213
|
+
) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
168
216
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (isNotNewlineStart(nodeMeta.childFirst)) {
|
|
179
|
-
context.report({
|
|
180
|
-
node: node,
|
|
181
|
-
messageId: MESSAGE_IDS.EXPECT_NEW_LINE_AFTER_OPEN,
|
|
182
|
-
data: { tag: label(node) },
|
|
183
|
-
fix(fixer) {
|
|
184
|
-
return fixer.insertTextAfter(node.openEnd, `\n`);
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
}
|
|
217
|
+
context.report({
|
|
218
|
+
node: current,
|
|
219
|
+
messageId: MESSAGE_IDS.EXPECT_NEW_LINE_AFTER,
|
|
220
|
+
data: { name: getName(current, { isClose: true }) },
|
|
221
|
+
fix(fixer) {
|
|
222
|
+
return fixer.insertTextAfter(current, `\n`);
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
});
|
|
189
226
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
fix(fixer) {
|
|
200
|
-
return fixer.insertTextBefore(node.close, `\n`);
|
|
201
|
-
},
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
227
|
+
childrenToCheck.forEach((child) => {
|
|
228
|
+
if (isTag(child)) {
|
|
229
|
+
/**
|
|
230
|
+
* @type {[OpenTagEnd, CloseTag] | undefined}
|
|
231
|
+
*/
|
|
232
|
+
const wrapper = child.close
|
|
233
|
+
? [child.openEnd, child.close]
|
|
234
|
+
: undefined;
|
|
235
|
+
checkChildren(child.children, child, wrapper);
|
|
206
236
|
}
|
|
237
|
+
});
|
|
207
238
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
messageId: MESSAGE_IDS.EXPECT_NEW_LINE_BEFORE,
|
|
225
|
-
data: { tag: label(nodeNext) },
|
|
226
|
-
fix(fixer) {
|
|
227
|
-
return fixer.insertTextBefore(nodeNext, `\n`);
|
|
228
|
-
},
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
}
|
|
239
|
+
const lastChild = childrenToCheck[childrenToCheck.length - 1];
|
|
240
|
+
if (
|
|
241
|
+
wrapper &&
|
|
242
|
+
lastChild &&
|
|
243
|
+
childrenToCheck.some((child) => !isInline(child))
|
|
244
|
+
) {
|
|
245
|
+
const close = wrapper[1];
|
|
246
|
+
if (isOnTheSameLine(close, lastChild)) {
|
|
247
|
+
context.report({
|
|
248
|
+
node: lastChild,
|
|
249
|
+
messageId: MESSAGE_IDS.EXPECT_NEW_LINE_AFTER,
|
|
250
|
+
data: { name: getName(lastChild, { isClose: true }) },
|
|
251
|
+
fix(fixer) {
|
|
252
|
+
return fixer.insertTextAfter(lastChild, `\n`);
|
|
253
|
+
},
|
|
254
|
+
});
|
|
232
255
|
}
|
|
233
256
|
}
|
|
234
|
-
|
|
235
|
-
return meta;
|
|
236
257
|
}
|
|
237
258
|
|
|
238
259
|
/**
|
|
239
|
-
* @param {
|
|
260
|
+
* @param {AnyNodeOrLine} node
|
|
261
|
+
* @returns {boolean}
|
|
240
262
|
*/
|
|
241
263
|
function isEmptyText(node) {
|
|
242
|
-
return
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
* @param {NewlineNode} node
|
|
247
|
-
*/
|
|
248
|
-
function isNotNewlineEnd(node) {
|
|
249
|
-
return node.type !== `Text` || /(\n|\r\n)\s*$/.test(node.value) === false;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* @param {NewlineNode} node
|
|
254
|
-
*/
|
|
255
|
-
function isNotNewlineStart(node) {
|
|
256
|
-
return node.type !== `Text` || /^(\n|\r\n)/.test(node.value) === false;
|
|
264
|
+
return (
|
|
265
|
+
(isText(node) && node.value.trim().length === 0) ||
|
|
266
|
+
(isLine(node) && node.value.trim().length === 0)
|
|
267
|
+
);
|
|
257
268
|
}
|
|
258
269
|
|
|
259
270
|
/**
|
|
260
|
-
* @param {
|
|
271
|
+
* @param {AnyNodeOrLine} node
|
|
261
272
|
* @param {{ isClose?: boolean }} options
|
|
262
273
|
*/
|
|
263
|
-
function
|
|
274
|
+
function getName(node, options = {}) {
|
|
264
275
|
const isClose = options.isClose || false;
|
|
265
276
|
if (isTag(node)) {
|
|
266
277
|
if (isClose) {
|
|
@@ -268,6 +279,24 @@ module.exports = {
|
|
|
268
279
|
}
|
|
269
280
|
return `<${node.name}>`;
|
|
270
281
|
}
|
|
282
|
+
if (isLine(node)) {
|
|
283
|
+
return "text";
|
|
284
|
+
}
|
|
285
|
+
if (isComment(node)) {
|
|
286
|
+
return "comment";
|
|
287
|
+
}
|
|
288
|
+
if (isScript(node)) {
|
|
289
|
+
if (isClose) {
|
|
290
|
+
return `</script>`;
|
|
291
|
+
}
|
|
292
|
+
return "<script>";
|
|
293
|
+
}
|
|
294
|
+
if (isStyle(node)) {
|
|
295
|
+
if (isClose) {
|
|
296
|
+
return `</style>`;
|
|
297
|
+
}
|
|
298
|
+
return "<style>";
|
|
299
|
+
}
|
|
271
300
|
return `<${node.type}>`;
|
|
272
301
|
}
|
|
273
302
|
|
|
@@ -287,26 +316,9 @@ module.exports = {
|
|
|
287
316
|
return result;
|
|
288
317
|
}
|
|
289
318
|
|
|
290
|
-
/**
|
|
291
|
-
* @param {NewlineNode} node
|
|
292
|
-
*/
|
|
293
|
-
function shouldBeNewline(node) {
|
|
294
|
-
if (isComment(node)) {
|
|
295
|
-
return /[\n\r]+/.test(node.value.value.trim());
|
|
296
|
-
}
|
|
297
|
-
if (isTag(node)) {
|
|
298
|
-
return inlineTags.includes(node.name.toLowerCase()) === false;
|
|
299
|
-
}
|
|
300
|
-
if (isText(node)) {
|
|
301
|
-
return /[\n\r]+/.test(node.value.trim());
|
|
302
|
-
}
|
|
303
|
-
return true;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
319
|
return createVisitors(context, {
|
|
307
320
|
Document(node) {
|
|
308
|
-
|
|
309
|
-
checkSiblings(node.children);
|
|
321
|
+
checkChildren(node.children, node);
|
|
310
322
|
},
|
|
311
323
|
});
|
|
312
324
|
},
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef { import("
|
|
3
|
-
* @typedef { import("
|
|
4
|
-
* @typedef { import("
|
|
5
|
-
*
|
|
2
|
+
* @typedef { import("@html-eslint/types").Tag } Tag
|
|
3
|
+
* @typedef { import("@html-eslint/types").ScriptTag } ScriptTag
|
|
4
|
+
* @typedef { import("@html-eslint/types").StyleTag } StyleTag
|
|
5
|
+
*
|
|
6
|
+
* @typedef {"camelCase" | "snake_case" | "PascalCase" | "kebab-case" | "regex"} Option1
|
|
7
|
+
* @typedef {Object} Option2
|
|
8
|
+
* @property {string} pattern
|
|
9
|
+
* @property {string} [flags]
|
|
10
|
+
*
|
|
11
|
+
* @typedef { import("../types").RuleModule<[Option1, Option2]> } RuleModule
|
|
6
12
|
*/
|
|
7
13
|
|
|
8
14
|
const { RULE_CATEGORY } = require("../constants");
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef { import("
|
|
3
|
-
* @typedef { import("../../types").AnyNode } AnyNode
|
|
2
|
+
* @typedef { import("@html-eslint/types").AnyNode } AnyNode
|
|
4
3
|
* @typedef { import("../../types").Line } Line
|
|
5
|
-
* @typedef { import("
|
|
4
|
+
* @typedef { import("@html-eslint/types").Tag } Tag
|
|
6
5
|
* @typedef { import("../../types").RuleListener } RuleListener
|
|
7
|
-
* @typedef { import("../../types").Context } Context
|
|
8
|
-
* @typedef { import("
|
|
6
|
+
* @typedef { import("../../types").Context<any[]> } Context
|
|
7
|
+
* @typedef { import("@html-eslint/types").TemplateText } TemplateText
|
|
9
8
|
* @typedef { import("eslint").AST.Token } Token
|
|
10
9
|
* @typedef { import("eslint").SourceCode } SourceCode
|
|
11
10
|
* @typedef { import("eslint").AST.Range } Range
|
|
12
11
|
* @typedef { import("eslint").AST.SourceLocation } SourceLocation
|
|
13
|
-
* @typedef { import("
|
|
14
|
-
*
|
|
12
|
+
* @typedef { import("@html-eslint/types").TemplateLiteral } TemplateLiteral
|
|
13
|
+
* @typedef { import("@html-eslint/types").OpenTemplate } OpenTemplate
|
|
14
|
+
* @typedef { import("@html-eslint/types").CloseTemplate } CloseTemplate
|
|
15
15
|
*
|
|
16
|
+
* @typedef {AnyNode | Line} AnyNodeOrLine
|
|
16
17
|
* @typedef {Object} IndentType
|
|
17
18
|
* @property {"tab"} TAB
|
|
18
19
|
* @property {"space"} SPACE
|
|
@@ -22,6 +23,13 @@
|
|
|
22
23
|
* @property {IndentType["TAB"] | IndentType["SPACE"]} indentType
|
|
23
24
|
* @property {number} indentSize
|
|
24
25
|
* @property {string} indentChar
|
|
26
|
+
*
|
|
27
|
+
* @typedef {"tab" | number} Option1
|
|
28
|
+
* @typedef {Object} Option2
|
|
29
|
+
* @property {number} [Option2.Attribute]
|
|
30
|
+
* @property {Record<string, number>} [Option2.tagChildrenIndent]
|
|
31
|
+
*
|
|
32
|
+
* @typedef { import("../../types").RuleModule<[Option1, Option2]> } RuleModule
|
|
25
33
|
*/
|
|
26
34
|
|
|
27
35
|
const { parse } = require("@html-eslint/template-parser");
|
|
@@ -145,9 +153,14 @@ module.exports = {
|
|
|
145
153
|
if (isTag(node)) {
|
|
146
154
|
return getTagIncreasingLevel(node);
|
|
147
155
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
156
|
+
const type = node.type;
|
|
157
|
+
if (type === NodeTypes.Attribute) {
|
|
158
|
+
const optionIndent = indentLevelOptions[type];
|
|
159
|
+
if (typeof optionIndent === "number") {
|
|
160
|
+
return optionIndent;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return 1;
|
|
151
164
|
}
|
|
152
165
|
|
|
153
166
|
/**
|
|
@@ -180,7 +193,7 @@ module.exports = {
|
|
|
180
193
|
let parentIgnoringChildCount = 0;
|
|
181
194
|
|
|
182
195
|
/**
|
|
183
|
-
* @param {AnyNode | Line | TemplateText} node
|
|
196
|
+
* @param {AnyNode | Line | TemplateText | OpenTemplate | CloseTemplate} node
|
|
184
197
|
* @returns {string}
|
|
185
198
|
*/
|
|
186
199
|
function getActualIndent(node) {
|
|
@@ -235,7 +248,7 @@ module.exports = {
|
|
|
235
248
|
}
|
|
236
249
|
|
|
237
250
|
/**
|
|
238
|
-
* @param {AnyNode | Line | TemplateText} node
|
|
251
|
+
* @param {AnyNode | Line | TemplateText | OpenTemplate | CloseTemplate} node
|
|
239
252
|
*/
|
|
240
253
|
function checkIndent(node) {
|
|
241
254
|
if (parentIgnoringChildCount > 0) {
|
|
@@ -250,11 +263,11 @@ module.exports = {
|
|
|
250
263
|
if (actualIndent !== expectedIndent) {
|
|
251
264
|
const targetNode = getIndentNodeToReport(node, actualIndent);
|
|
252
265
|
context.report({
|
|
253
|
-
|
|
266
|
+
loc: targetNode.loc,
|
|
254
267
|
messageId: MESSAGE_ID.WRONG_INDENT,
|
|
255
268
|
data: getMessageData(actualIndent, indentLevel.value()),
|
|
256
269
|
fix(fixer) {
|
|
257
|
-
return fixer.
|
|
270
|
+
return fixer.replaceTextRange(targetNode.range, expectedIndent);
|
|
258
271
|
},
|
|
259
272
|
});
|
|
260
273
|
}
|
|
@@ -396,7 +409,7 @@ module.exports = {
|
|
|
396
409
|
};
|
|
397
410
|
|
|
398
411
|
/**
|
|
399
|
-
* @param {
|
|
412
|
+
* @param {AnyNodeOrLine | TemplateText | OpenTemplate | CloseTemplate} node
|
|
400
413
|
* @param {string} actualIndent
|
|
401
414
|
* @return {{range: Range; loc: SourceLocation}}
|
|
402
415
|
*/
|
package/lib/rules/lowercase.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef { import("
|
|
3
|
-
* @typedef { import("
|
|
4
|
-
* @typedef { import("
|
|
5
|
-
* @typedef { import("../types").
|
|
2
|
+
* @typedef { import("@html-eslint/types").Tag } Tag
|
|
3
|
+
* @typedef { import("@html-eslint/types").StyleTag } StyleTag
|
|
4
|
+
* @typedef { import("@html-eslint/types").ScriptTag } ScriptTag
|
|
5
|
+
* @typedef { import("../types").RuleModule<[]> } RuleModule
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const { NODE_TYPES } = require("@html-eslint/parser");
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef { import("
|
|
3
|
-
* @typedef { import("
|
|
4
|
-
* @typedef { import("
|
|
5
|
-
*
|
|
2
|
+
* @typedef { import("@html-eslint/types").Tag } Tag
|
|
3
|
+
* @typedef { import("@html-eslint/types").StyleTag } StyleTag
|
|
4
|
+
* @typedef { import("@html-eslint/types").ScriptTag } ScriptTag
|
|
5
|
+
*
|
|
6
|
+
* @typedef {Object} Option
|
|
7
|
+
* @property {number} [Option.max]
|
|
8
|
+
* @typedef { import("../types").RuleModule<[Option]> } RuleModule
|
|
6
9
|
*/
|
|
7
10
|
|
|
8
11
|
const { RULE_CATEGORY } = require("../constants");
|
|
@@ -71,7 +74,7 @@ module.exports = {
|
|
|
71
74
|
node,
|
|
72
75
|
messageId: MESSAGE_IDS.MAX_DEPTH_EXCEEDED,
|
|
73
76
|
data: {
|
|
74
|
-
needed: maxDepth
|
|
77
|
+
needed: `${maxDepth}`,
|
|
75
78
|
found: String(depth),
|
|
76
79
|
},
|
|
77
80
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef { import("
|
|
3
|
-
* @typedef { import("
|
|
4
|
-
* @typedef { import("
|
|
5
|
-
* @typedef { import("../types").
|
|
2
|
+
* @typedef { import("@html-eslint/types").Tag } Tag
|
|
3
|
+
* @typedef { import("@html-eslint/types").StyleTag } StyleTag
|
|
4
|
+
* @typedef { import("@html-eslint/types").ScriptTag } ScriptTag
|
|
5
|
+
* @typedef { import("../types").RuleModule<[]> } RuleModule
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const { RULE_CATEGORY } = require("../constants");
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef { import("
|
|
3
|
-
* @typedef { import("
|
|
4
|
-
* @typedef { import("
|
|
5
|
-
* @typedef { import("../types").
|
|
2
|
+
* @typedef { import("@html-eslint/types").Tag } Tag
|
|
3
|
+
* @typedef { import("@html-eslint/types").StyleTag } StyleTag
|
|
4
|
+
* @typedef { import("@html-eslint/types").ScriptTag } ScriptTag
|
|
5
|
+
* @typedef { import("../types").RuleModule<[]> } RuleModule
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const { RULE_CATEGORY } = require("../constants");
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef { import("
|
|
3
|
-
* @typedef { import("
|
|
4
|
-
* @typedef { import("
|
|
5
|
-
* @typedef { import("../types").
|
|
2
|
+
* @typedef { import("@html-eslint/types").Tag } Tag
|
|
3
|
+
* @typedef { import("@html-eslint/types").StyleTag } StyleTag
|
|
4
|
+
* @typedef { import("@html-eslint/types").ScriptTag } ScriptTag
|
|
5
|
+
* @typedef { import("../types").RuleModule<[]> } RuleModule
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const { RULE_CATEGORY } = require("../constants");
|