@html-eslint/eslint-plugin 0.31.0 → 0.31.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.
@@ -83,16 +83,7 @@ module.exports = {
83
83
  create(context) {
84
84
  const sourceCode = getSourceCode(context);
85
85
  const indentLevelOptions = (context.options && context.options[1]) || {};
86
- const indentLevel = new IndentLevel({
87
- getIncreasingLevel(node) {
88
- return typeof indentLevelOptions[node.type] === "number"
89
- ? indentLevelOptions[node.type]
90
- : 1;
91
- },
92
- });
93
-
94
- let parentIgnoringChildCount = 0;
95
-
86
+ const lines = sourceCode.getLines();
96
87
  const { indentType, indentSize, indentChar } = (function () {
97
88
  const options = context.options;
98
89
  /**
@@ -129,270 +120,248 @@ module.exports = {
129
120
  }
130
121
 
131
122
  /**
132
- * @param {AnyNode} node
133
- * @returns {string}
123
+ *
124
+ * @param {TemplateLiteral} node
125
+ * @returns {number}
134
126
  */
135
- function getActualIndent(node) {
136
- const lines = sourceCode.getLines();
137
- const line = lines[node.loc.start.line - 1];
138
- let column = node.loc.start.column;
127
+ function getTemplateLiteralBaseIndentLevel(node) {
128
+ // @ts-ignore
129
+ const lineIndex = node.loc.start.line - 1;
130
+ const line = lines[lineIndex];
139
131
 
140
- if (isLineNode(node)) {
141
- column += countLeftPadding(node.value);
132
+ const spaceCount = countLeftPadding(line);
133
+ if (indentType === "space") {
134
+ return Math.floor(spaceCount / indentSize) + 1;
135
+ } else {
136
+ return spaceCount + 1;
142
137
  }
143
-
144
- return line.slice(0, column);
145
138
  }
146
139
 
147
140
  /**
148
- * @returns {string}
149
- */
150
- function getExpectedIndent() {
151
- return indentChar.repeat(indentLevel.value());
152
- }
153
-
154
- /**
155
- * @param {AnyNode} node
156
- * @param {string} actualIndent
157
- * @return {BaseNode}
141
+ * @param {number} baseLevel
158
142
  */
159
- function getIndentNodeToReport(node, actualIndent) {
160
- let rangeStart = node.range[0];
143
+ function createIndentVisitor(baseLevel) {
144
+ const indentLevel = new IndentLevel({
145
+ getIncreasingLevel(node) {
146
+ return typeof indentLevelOptions[node.type] === "number"
147
+ ? indentLevelOptions[node.type]
148
+ : 1;
149
+ },
150
+ });
151
+ indentLevel.setBase(baseLevel);
161
152
 
162
- if (node.type !== "Line") {
163
- rangeStart -= actualIndent.length;
164
- }
153
+ let parentIgnoringChildCount = 0;
165
154
 
166
- return {
167
- range: [rangeStart, rangeStart + actualIndent.length],
168
- loc: {
169
- start: {
170
- column: 0,
171
- line: node.loc.start.line,
172
- },
173
- end: {
174
- column: actualIndent.length,
175
- line: node.loc.start.line,
176
- },
177
- },
178
- };
179
- }
155
+ /**
156
+ * @param {AnyNode} node
157
+ * @returns {string}
158
+ */
159
+ function getActualIndent(node) {
160
+ const lines = sourceCode.getLines();
161
+ const line = lines[node.loc.start.line - 1];
162
+ let column = node.loc.start.column;
180
163
 
181
- /**
182
- * @param {string} actualIndent
183
- * @param {number} expectedIndentSize
184
- */
185
- function getMessageData(actualIndent, expectedIndentSize) {
186
- const actualTabs = (actualIndent.match(/\t/g) || []).length;
187
- const actualSpaces = (actualIndent.match(/[^\S\t\n\r]/g) || []).length;
188
- let actual = "";
189
- if (!actualTabs && !actualSpaces) {
190
- actual = "no indent";
191
- } else {
192
- if (actualTabs) {
193
- actual += `${actualTabs} tab`;
194
- }
195
- if (actualSpaces) {
196
- if (actual) {
197
- actual += ", ";
198
- }
199
- actual += `${actualSpaces} space`;
164
+ if (isLineNode(node)) {
165
+ column += countLeftPadding(node.value);
200
166
  }
167
+
168
+ return line.slice(0, column);
201
169
  }
202
170
 
203
- if (indentType === "space") {
204
- expectedIndentSize *= indentSize;
171
+ /**
172
+ * @returns {string}
173
+ */
174
+ function getExpectedIndent() {
175
+ return indentChar.repeat(indentLevel.value());
205
176
  }
206
177
 
207
- return {
208
- actual,
209
- expected: `${expectedIndentSize} ${indentType}`,
210
- };
211
- }
178
+ /**
179
+ * @param {AnyNode} node
180
+ * @param {string} actualIndent
181
+ * @return {BaseNode}
182
+ */
183
+ function getIndentNodeToReport(node, actualIndent) {
184
+ let rangeStart = node.range[0];
212
185
 
213
- /**
214
- * @param {AnyNode} node
215
- */
216
- function checkIndent(node) {
217
- if (parentIgnoringChildCount > 0) {
218
- return;
219
- }
220
- const actualIndent = getActualIndent(node);
221
- const expectedIndent = getExpectedIndent();
186
+ if (node.type !== "Line") {
187
+ rangeStart -= actualIndent.length;
188
+ }
222
189
 
223
- if (actualIndent.trim().length) {
224
- return;
225
- }
226
- if (actualIndent !== expectedIndent) {
227
- const targetNode = getIndentNodeToReport(node, actualIndent);
228
- context.report({
229
- node: targetNode,
230
- messageId: MESSAGE_ID.WRONG_INDENT,
231
- data: getMessageData(actualIndent, indentLevel.value()),
232
- fix(fixer) {
233
- return fixer.replaceText(targetNode, expectedIndent);
190
+ return {
191
+ range: [rangeStart, rangeStart + actualIndent.length],
192
+ loc: {
193
+ start: {
194
+ column: 0,
195
+ line: node.loc.start.line,
196
+ },
197
+ end: {
198
+ column: actualIndent.length,
199
+ line: node.loc.start.line,
200
+ },
234
201
  },
235
- });
202
+ };
236
203
  }
237
- }
238
204
 
239
- /**
240
- *
241
- * @param {Token} token
242
- */
243
- function getBaseIndentToken(token) {
244
205
  /**
245
- * @type {Token | null}
206
+ * @param {string} actualIndent
207
+ * @param {number} expectedIndentSize
246
208
  */
247
- let currentToken = token;
248
- let tokenBefore = token;
249
-
250
- while (
251
- // @ts-ignore
252
- (tokenBefore = sourceCode.getTokenBefore(currentToken, {
253
- includeComments: true,
254
- }))
255
- ) {
256
- if (!tokenBefore) {
257
- return currentToken;
209
+ function getMessageData(actualIndent, expectedIndentSize) {
210
+ const actualTabs = (actualIndent.match(/\t/g) || []).length;
211
+ const actualSpaces = (actualIndent.match(/[^\S\t\n\r]/g) || []).length;
212
+ let actual = "";
213
+ if (!actualTabs && !actualSpaces) {
214
+ actual = "no indent";
215
+ } else {
216
+ if (actualTabs) {
217
+ actual += `${actualTabs} tab`;
218
+ }
219
+ if (actualSpaces) {
220
+ if (actual) {
221
+ actual += ", ";
222
+ }
223
+ actual += `${actualSpaces} space`;
224
+ }
258
225
  }
259
- if (tokenBefore.loc.start.line !== currentToken.loc.start.line) {
260
- return currentToken;
226
+
227
+ if (indentType === "space") {
228
+ expectedIndentSize *= indentSize;
261
229
  }
262
- currentToken = tokenBefore;
263
- }
264
- return tokenBefore;
265
- }
266
230
 
267
- /**
268
- *
269
- * @param {TemplateLiteral} node
270
- * @returns {number}
271
- */
272
- function getBaseIndentLevel(node) {
273
- const firstToken = sourceCode.getFirstToken(node);
274
- if (!firstToken) return 0;
275
- const baseToken = getBaseIndentToken(firstToken);
276
- if (!baseToken) {
277
- return 0;
231
+ return {
232
+ actual,
233
+ expected: `${expectedIndentSize} ${indentType}`,
234
+ };
278
235
  }
279
- const spaceCount = baseToken.loc.start.column;
280
236
 
281
- if (indentType === "space") {
282
- return Math.floor(spaceCount / indentSize);
283
- } else {
284
- return spaceCount;
285
- }
286
- }
287
- /**
288
- * @type {RuleListener}
289
- */
290
- const visitor = {
291
- Tag(node) {
292
- if (IGNORING_NODES.includes(node.name)) {
293
- parentIgnoringChildCount++;
294
- }
295
- indentLevel.indent(node);
296
- },
297
- ScriptTag(node) {
298
- indentLevel.indent(node);
299
- },
300
- "ScriptTag:exit"(node) {
301
- indentLevel.dedent(node);
302
- },
303
- OpenScriptTagStart: checkIndent,
304
- OpenScriptTagEnd: checkIndent,
305
- StyleTag(node) {
306
- indentLevel.indent(node);
307
- },
308
- "StyleTag:exit"(node) {
309
- indentLevel.dedent(node);
310
- },
311
- OpenStyleTagStart: checkIndent,
312
- OpenStyleTagEnd: checkIndent,
313
- OpenTagStart: checkIndent,
314
- OpenTagEnd: checkIndent,
315
- CloseTag: checkIndent,
316
- "Tag:exit"(node) {
317
- if (IGNORING_NODES.includes(node.name)) {
318
- parentIgnoringChildCount--;
237
+ /**
238
+ * @param {AnyNode} node
239
+ */
240
+ function checkIndent(node) {
241
+ if (parentIgnoringChildCount > 0) {
242
+ return;
319
243
  }
320
- indentLevel.dedent(node);
321
- },
244
+ const actualIndent = getActualIndent(node);
245
+ const expectedIndent = getExpectedIndent();
322
246
 
323
- // Attribute
324
- Attribute(node) {
325
- indentLevel.indent(node);
326
- },
327
- AttributeKey: checkIndent,
328
- AttributeValue: checkIndent,
329
- "Attribute:exit"(node) {
330
- indentLevel.dedent(node);
331
- },
247
+ if (actualIndent.trim().length) {
248
+ return;
249
+ }
250
+ if (actualIndent !== expectedIndent) {
251
+ const targetNode = getIndentNodeToReport(node, actualIndent);
252
+ context.report({
253
+ node: targetNode,
254
+ messageId: MESSAGE_ID.WRONG_INDENT,
255
+ data: getMessageData(actualIndent, indentLevel.value()),
256
+ fix(fixer) {
257
+ return fixer.replaceText(targetNode, expectedIndent);
258
+ },
259
+ });
260
+ }
261
+ }
332
262
 
333
- // Text
334
- Text(node) {
335
- indentLevel.indent(node);
336
- const lineNodes = splitToLineNodes(node);
337
- lineNodes.forEach((lineNode) => {
338
- if (lineNode.skipIndentCheck) {
339
- return;
340
- }
341
- if (lineNode.value.trim().length) {
342
- checkIndent(lineNode);
343
- }
344
- });
345
- },
346
- "Text:exit"(node) {
347
- indentLevel.dedent(node);
348
- },
349
- Comment(node) {
350
- indentLevel.indent(node);
351
- },
352
- CommentOpen: checkIndent,
353
- CommentContent(node) {
354
- indentLevel.indent(node);
355
- const lineNodes = splitToLineNodes(node);
356
- lineNodes.forEach((lineNode) => {
357
- if (lineNode.skipIndentCheck) {
358
- return;
263
+ /**
264
+ * @type {RuleListener}
265
+ */
266
+ const visitor = {
267
+ Tag(node) {
268
+ if (IGNORING_NODES.includes(node.name)) {
269
+ parentIgnoringChildCount++;
359
270
  }
360
- if (lineNode.value.trim().length) {
361
- checkIndent(lineNode);
271
+ indentLevel.indent(node);
272
+ },
273
+ ScriptTag(node) {
274
+ indentLevel.indent(node);
275
+ },
276
+ "ScriptTag:exit"(node) {
277
+ indentLevel.dedent(node);
278
+ },
279
+ OpenScriptTagStart: checkIndent,
280
+ OpenScriptTagEnd: checkIndent,
281
+ StyleTag(node) {
282
+ indentLevel.indent(node);
283
+ },
284
+ "StyleTag:exit"(node) {
285
+ indentLevel.dedent(node);
286
+ },
287
+ OpenStyleTagStart: checkIndent,
288
+ OpenStyleTagEnd: checkIndent,
289
+ OpenTagStart: checkIndent,
290
+ OpenTagEnd: checkIndent,
291
+ CloseTag: checkIndent,
292
+ "Tag:exit"(node) {
293
+ if (IGNORING_NODES.includes(node.name)) {
294
+ parentIgnoringChildCount--;
362
295
  }
363
- });
364
- },
365
- CommentClose: checkIndent,
366
- "Comment:exit"(node) {
367
- indentLevel.dedent(node);
368
- },
369
- "CommentContent:exit"(node) {
370
- indentLevel.dedent(node);
371
- },
372
- };
296
+ indentLevel.dedent(node);
297
+ },
298
+
299
+ // Attribute
300
+ Attribute(node) {
301
+ indentLevel.indent(node);
302
+ },
303
+ AttributeKey: checkIndent,
304
+ AttributeValue: checkIndent,
305
+ "Attribute:exit"(node) {
306
+ indentLevel.dedent(node);
307
+ },
308
+
309
+ // Text
310
+ Text(node) {
311
+ indentLevel.indent(node);
312
+ const lineNodes = splitToLineNodes(node);
313
+
314
+ lineNodes.forEach((lineNode) => {
315
+ if (lineNode.skipIndentCheck) {
316
+ return;
317
+ }
318
+ if (lineNode.value.trim().length) {
319
+ checkIndent(lineNode);
320
+ }
321
+ });
322
+ },
323
+ "Text:exit"(node) {
324
+ indentLevel.dedent(node);
325
+ },
326
+ Comment(node) {
327
+ indentLevel.indent(node);
328
+ },
329
+ CommentOpen: checkIndent,
330
+ CommentContent(node) {
331
+ indentLevel.indent(node);
332
+ const lineNodes = splitToLineNodes(node);
333
+ lineNodes.forEach((lineNode) => {
334
+ if (lineNode.skipIndentCheck) {
335
+ return;
336
+ }
337
+ if (lineNode.value.trim().length) {
338
+ checkIndent(lineNode);
339
+ }
340
+ });
341
+ },
342
+ CommentClose: checkIndent,
343
+ "Comment:exit"(node) {
344
+ indentLevel.dedent(node);
345
+ },
346
+ "CommentContent:exit"(node) {
347
+ indentLevel.dedent(node);
348
+ },
349
+ };
350
+ return visitor;
351
+ }
373
352
 
374
353
  return {
375
- ...visitor,
354
+ ...createIndentVisitor(0),
376
355
  TaggedTemplateExpression(node) {
377
356
  if (shouldCheckTaggedTemplateExpression(node, context)) {
378
- indentLevel.setBase(getBaseIndentLevel(node.quasi) + 1);
379
- parse(node.quasi, getSourceCode(context), visitor);
380
- }
381
- },
382
- "TaggedTemplateExpression:exit"(node) {
383
- if (shouldCheckTaggedTemplateExpression(node, context)) {
384
- indentLevel.setBase(0);
357
+ const base = getTemplateLiteralBaseIndentLevel(node.quasi);
358
+ parse(node.quasi, getSourceCode(context), createIndentVisitor(base));
385
359
  }
386
360
  },
387
361
  TemplateLiteral(node) {
388
362
  if (shouldCheckTemplateLiteral(node, context)) {
389
- indentLevel.setBase(getBaseIndentLevel(node) + 1);
390
- parse(node, getSourceCode(context), visitor);
391
- }
392
- },
393
- "TemplateLiteral:exit"(node) {
394
- if (shouldCheckTemplateLiteral(node, context)) {
395
- indentLevel.setBase(0);
363
+ const base = getTemplateLiteralBaseIndentLevel(node);
364
+ parse(node, getSourceCode(context), createIndentVisitor(base));
396
365
  }
397
366
  },
398
367
  };
@@ -86,30 +86,10 @@ function splitToLineNodes(node) {
86
86
  * @param {import("../../types").Range} range
87
87
  */
88
88
  function shouldSkipIndentCheck(range) {
89
- const overlappedTemplates = templates.filter(
89
+ return templates.some(
90
90
  (template) =>
91
91
  template.isTemplate && isRangesOverlap(template.range, range)
92
92
  );
93
-
94
- const isLineInTemplate = overlappedTemplates.some((template) => {
95
- return template.range[0] <= range[0] && template.range[1] >= range[1];
96
- });
97
- if (isLineInTemplate) {
98
- return true;
99
- }
100
- const isLineBeforeTemplate = overlappedTemplates.some((template) => {
101
- return template.range[0] <= range[0] && template.range[1] <= range[1];
102
- });
103
- if (isLineBeforeTemplate) {
104
- return true;
105
- }
106
- const isLineAfterTemplate = overlappedTemplates.some((template) => {
107
- return template.range[1] <= range[0];
108
- });
109
- if (isLineAfterTemplate) {
110
- return true;
111
- }
112
- return false;
113
93
  }
114
94
 
115
95
  node.value.split("\n").forEach((value, index) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@html-eslint/eslint-plugin",
3
- "version": "0.31.0",
3
+ "version": "0.31.1",
4
4
  "description": "ESLint plugin for html",
5
5
  "author": "yeonjuan",
6
6
  "homepage": "https://github.com/yeonjuan/html-eslint#readme",
@@ -55,5 +55,5 @@
55
55
  "espree": "^10.3.0",
56
56
  "typescript": "^5.7.2"
57
57
  },
58
- "gitHead": "0e9ece917af191d223ccec4b17d9096f02a96508"
58
+ "gitHead": "96d3cb165f2d777d36e7efbba174e46f437faec0"
59
59
  }
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../lib/rules/utils/node.js"],"names":[],"mappings":"sBACc,OAAO,gBAAgB,EAAE,OAAO;4BAChC,OAAO,gBAAgB,EAAE,aAAa;2BACtC,OAAO,gBAAgB,EAAE,YAAY;4BACrC,OAAO,gBAAgB,EAAE,aAAa;iCACtC,OAAO,gBAAgB,EAAE,kBAAkB;sBAC3C,OAAO,gBAAgB,EAAE,OAAO;uBAChC,OAAO,gBAAgB,EAAE,QAAQ;iCACjC,OAAO,gBAAgB,EAAE,kBAAkB;0BAC3C,OAAO,gBAAgB,EAAE,WAAW;uBACpC,OAAO,gBAAgB,EAAE,QAAQ;uBACjC,OAAO,aAAa,EAAE,QAAQ;uBAC9B,OAAO,aAAa,EAAE,QAAQ;uBAC9B,OAAO,aAAa,EAAE,QAAQ;oBAC9B,OAAO,aAAa,EAAE,KAAK;AAKzC;;;;GAIG;AACH,+BAJW,OAAO,GAAG,aAAa,GAAG,YAAY,OACtC,MAAM,GACJ,aAAa,GAAG,SAAS,CAMrC;AAED;;;;GAIG;AACH,wCAHW,OAAO,GAAG,aAAa,GAAG,YAAY,GACpC,OAAO,CAInB;AAED;;;;GAIG;AACH,6CAHW,OAAO,GACL,OAAO,CAInB;AAuBD;;;;GAIG;AACH,uCAHW,QAAQ,GAAG,kBAAkB,GAC3B,QAAQ,EAAE,CA4EtB;AAED;;;;;GAKG;AACH,sCAJW,QAAQ,SACR,QAAQ,GACN,QAAQ,CAOpB;AAED;;;GAGG;AACH,6CAHW,kBAAkB,GACjB,OAAO,CAOlB;AAED;;;GAGG;AACH,4BAHW,OAAO,GACL,IAAI,IAAI,OAAO,CAI3B;AAED;;;GAGG;AACH,gCAHW,OAAO,GACL,IAAI,IAAI,WAAW,CAI/B;AAED;;;GAGG;AACH,6BAHW,OAAO,GACL,IAAI,IAAI,QAAQ,CAI5B;AA1ID;;;;GAIG;AACH,kDAJW,CAAC,QAAQ,GAAG,kBAAkB,CAAC,CAAC,WAAW,CAAC,SAC5C,KAAK,GACH,OAAO,CAMnB;AAqID;;;GAGG;AACH,oCAHW,MAAM,GACJ,MAAM,EAAE,CAIpB;AA9JD;;;;;GAKG;AACH,wCAJW,KAAK,UACL,KAAK,GACH,OAAO,CAInB;AAwJD;;;;GAIG;AACH,0CAHW,QAAQ,EAAE,GACR,CAAC,CAAC,kBAAkB,GAAG,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAapE"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../lib/rules/utils/node.js"],"names":[],"mappings":"sBACc,OAAO,gBAAgB,EAAE,OAAO;4BAChC,OAAO,gBAAgB,EAAE,aAAa;2BACtC,OAAO,gBAAgB,EAAE,YAAY;4BACrC,OAAO,gBAAgB,EAAE,aAAa;iCACtC,OAAO,gBAAgB,EAAE,kBAAkB;sBAC3C,OAAO,gBAAgB,EAAE,OAAO;uBAChC,OAAO,gBAAgB,EAAE,QAAQ;iCACjC,OAAO,gBAAgB,EAAE,kBAAkB;0BAC3C,OAAO,gBAAgB,EAAE,WAAW;uBACpC,OAAO,gBAAgB,EAAE,QAAQ;uBACjC,OAAO,aAAa,EAAE,QAAQ;uBAC9B,OAAO,aAAa,EAAE,QAAQ;uBAC9B,OAAO,aAAa,EAAE,QAAQ;oBAC9B,OAAO,aAAa,EAAE,KAAK;AAKzC;;;;GAIG;AACH,+BAJW,OAAO,GAAG,aAAa,GAAG,YAAY,OACtC,MAAM,GACJ,aAAa,GAAG,SAAS,CAMrC;AAED;;;;GAIG;AACH,wCAHW,OAAO,GAAG,aAAa,GAAG,YAAY,GACpC,OAAO,CAInB;AAED;;;;GAIG;AACH,6CAHW,OAAO,GACL,OAAO,CAInB;AAuBD;;;;GAIG;AACH,uCAHW,QAAQ,GAAG,kBAAkB,GAC3B,QAAQ,EAAE,CAwDtB;AAED;;;;;GAKG;AACH,sCAJW,QAAQ,SACR,QAAQ,GACN,QAAQ,CAOpB;AAED;;;GAGG;AACH,6CAHW,kBAAkB,GACjB,OAAO,CAOlB;AAED;;;GAGG;AACH,4BAHW,OAAO,GACL,IAAI,IAAI,OAAO,CAI3B;AAED;;;GAGG;AACH,gCAHW,OAAO,GACL,IAAI,IAAI,WAAW,CAI/B;AAED;;;GAGG;AACH,6BAHW,OAAO,GACL,IAAI,IAAI,QAAQ,CAI5B;AAtHD;;;;GAIG;AACH,kDAJW,CAAC,QAAQ,GAAG,kBAAkB,CAAC,CAAC,WAAW,CAAC,SAC5C,KAAK,GACH,OAAO,CAMnB;AAiHD;;;GAGG;AACH,oCAHW,MAAM,GACJ,MAAM,EAAE,CAIpB;AA1ID;;;;;GAKG;AACH,wCAJW,KAAK,UACL,KAAK,GACH,OAAO,CAInB;AAoID;;;;GAIG;AACH,0CAHW,QAAQ,EAAE,GACR,CAAC,CAAC,kBAAkB,GAAG,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAapE"}