@html-eslint/eslint-plugin 0.29.0 → 0.30.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.
@@ -4,6 +4,10 @@
4
4
  * @typedef { import("../types").LineNode } LineNode
5
5
  * @typedef { import("../types").BaseNode } BaseNode
6
6
  * @typedef { import("../types").TagNode } TagNode
7
+ * @typedef { import("../types").RuleListener } RuleListener
8
+ * @typedef { import("eslint").AST.Token } Token
9
+ * @typedef { import("eslint").SourceCode } SourceCode
10
+ * @typedef { import("estree").TemplateLiteral } TemplateLiteral
7
11
  * @typedef {Object} IndentType
8
12
  * @property {"tab"} TAB
9
13
  * @property {"space"} SPACE
@@ -11,10 +15,14 @@
11
15
  * @property {"wrongIndent"} WRONG_INDENT
12
16
  */
13
17
 
18
+ const { parse } = require("@html-eslint/template-parser");
14
19
  const { RULE_CATEGORY } = require("../constants");
15
20
  const { splitToLineNodes } = require("./utils/node");
21
+ const {
22
+ shouldCheckTaggedTemplateExpression,
23
+ shouldCheckTemplateLiteral,
24
+ } = require("./utils/settings");
16
25
  const { getSourceCode } = require("./utils/source-code");
17
- const { createVisitors } = require("./utils/visitors");
18
26
 
19
27
  /** @type {MessageId} */
20
28
  const MESSAGE_ID = {
@@ -63,6 +71,8 @@ module.exports = {
63
71
  },
64
72
  create(context) {
65
73
  const sourceCode = getSourceCode(context);
74
+
75
+ let baseIndentLevel = 0;
66
76
  let indentLevel = -1;
67
77
  let parentIgnoringChildCount = 0;
68
78
 
@@ -91,6 +101,9 @@ module.exports = {
91
101
  function unindent() {
92
102
  indentLevel--;
93
103
  }
104
+ function getIndentLevel() {
105
+ return indentLevel + baseIndentLevel;
106
+ }
94
107
 
95
108
  /**
96
109
  * @param {string} str
@@ -128,7 +141,7 @@ module.exports = {
128
141
  * @returns {string}
129
142
  */
130
143
  function getExpectedIndent() {
131
- return indentChar.repeat(indentLevel);
144
+ return indentChar.repeat(getIndentLevel());
132
145
  }
133
146
 
134
147
  /**
@@ -199,6 +212,7 @@ module.exports = {
199
212
  }
200
213
  const actualIndent = getActualIndent(node);
201
214
  const expectedIndent = getExpectedIndent();
215
+
202
216
  if (actualIndent.trim().length) {
203
217
  return;
204
218
  }
@@ -207,7 +221,7 @@ module.exports = {
207
221
  context.report({
208
222
  node: targetNode,
209
223
  messageId: MESSAGE_ID.WRONG_INDENT,
210
- data: getMessageData(actualIndent, indentLevel),
224
+ data: getMessageData(actualIndent, getIndentLevel()),
211
225
  fix(fixer) {
212
226
  return fixer.replaceText(targetNode, expectedIndent);
213
227
  },
@@ -215,7 +229,58 @@ module.exports = {
215
229
  }
216
230
  }
217
231
 
218
- return createVisitors(context, {
232
+ /**
233
+ *
234
+ * @param {Token} token
235
+ */
236
+ function getBaseIndentToken(token) {
237
+ /**
238
+ * @type {Token | null}
239
+ */
240
+ let currentToken = token;
241
+ let tokenBefore = token;
242
+
243
+ while (
244
+ // @ts-ignore
245
+ (tokenBefore = sourceCode.getTokenBefore(currentToken, {
246
+ includeComments: true,
247
+ }))
248
+ ) {
249
+ if (!tokenBefore) {
250
+ return currentToken;
251
+ }
252
+ if (tokenBefore.loc.start.line !== currentToken.loc.start.line) {
253
+ return currentToken;
254
+ }
255
+ currentToken = tokenBefore;
256
+ }
257
+ return tokenBefore;
258
+ }
259
+
260
+ /**
261
+ *
262
+ * @param {TemplateLiteral} node
263
+ * @returns {number}
264
+ */
265
+ function getBaseIndentLevel(node) {
266
+ const firstToken = sourceCode.getFirstToken(node);
267
+ if (!firstToken) return 0;
268
+ const baseToken = getBaseIndentToken(firstToken);
269
+ if (!baseToken) {
270
+ return 0;
271
+ }
272
+ const spaceCount = baseToken.loc.start.column;
273
+
274
+ if (indentType === "space") {
275
+ return Math.floor(spaceCount / indentSize);
276
+ } else {
277
+ return spaceCount;
278
+ }
279
+ }
280
+ /**
281
+ * @type {RuleListener}
282
+ */
283
+ const visitor = {
219
284
  Tag(node) {
220
285
  if (IGNORING_NODES.includes(node.name)) {
221
286
  parentIgnoringChildCount++;
@@ -282,6 +347,32 @@ module.exports = {
282
347
  CommentClose: checkIndent,
283
348
  "Comment:exit": unindent,
284
349
  "CommentContent:exit": unindent,
285
- });
350
+ };
351
+
352
+ return {
353
+ ...visitor,
354
+ TaggedTemplateExpression(node) {
355
+ if (shouldCheckTaggedTemplateExpression(node, context)) {
356
+ baseIndentLevel = getBaseIndentLevel(node.quasi) + 1;
357
+ parse(node.quasi, getSourceCode(context), visitor);
358
+ }
359
+ },
360
+ "TaggedTemplateExpression:exit"(node) {
361
+ if (shouldCheckTaggedTemplateExpression(node, context)) {
362
+ baseIndentLevel = 0;
363
+ }
364
+ },
365
+ TemplateLiteral(node) {
366
+ if (shouldCheckTemplateLiteral(node, context)) {
367
+ baseIndentLevel = getBaseIndentLevel(node) + 1;
368
+ parse(node, getSourceCode(context), visitor);
369
+ }
370
+ },
371
+ "TemplateLiteral:exit"(node) {
372
+ if (shouldCheckTemplateLiteral(node, context)) {
373
+ baseIndentLevel = 0;
374
+ }
375
+ },
376
+ };
286
377
  },
287
378
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@html-eslint/eslint-plugin",
3
- "version": "0.29.0",
3
+ "version": "0.30.0",
4
4
  "description": "ESLint plugin for html",
5
5
  "author": "yeonjuan",
6
6
  "homepage": "https://github.com/yeonjuan/html-eslint#readme",
@@ -45,15 +45,15 @@
45
45
  "accessibility"
46
46
  ],
47
47
  "dependencies": {
48
- "@html-eslint/template-parser": "^0.29.0"
48
+ "@html-eslint/template-parser": "^0.30.0"
49
49
  },
50
50
  "devDependencies": {
51
- "@html-eslint/parser": "^0.29.0",
51
+ "@html-eslint/parser": "^0.30.0",
52
52
  "@types/eslint": "^9.6.1",
53
53
  "@types/estree": "^0.0.47",
54
54
  "es-html-parser": "^1.0.0-alpha.4",
55
55
  "espree": "^10.3.0",
56
56
  "typescript": "^5.7.2"
57
57
  },
58
- "gitHead": "e8908db01b8bd4a682227a2144c0dd5588fc347e"
58
+ "gitHead": "29f274f996d9cd41b82f2f2fa5c642564d3bc756"
59
59
  }
@@ -1,5 +1,5 @@
1
1
  declare namespace _exports {
2
- export { RuleModule, AnyNode, LineNode, BaseNode, TagNode, IndentType, MessageId };
2
+ export { RuleModule, AnyNode, LineNode, BaseNode, TagNode, RuleListener, Token, SourceCode, TemplateLiteral, IndentType, MessageId };
3
3
  }
4
4
  declare const _exports: RuleModule;
5
5
  export = _exports;
@@ -8,6 +8,10 @@ type AnyNode = import("../types").AnyNode;
8
8
  type LineNode = import("../types").LineNode;
9
9
  type BaseNode = import("../types").BaseNode;
10
10
  type TagNode = import("../types").TagNode;
11
+ type RuleListener = import("../types").RuleListener;
12
+ type Token = import("eslint").AST.Token;
13
+ type SourceCode = import("eslint").SourceCode;
14
+ type TemplateLiteral = import("estree").TemplateLiteral;
11
15
  type IndentType = {
12
16
  TAB: "tab";
13
17
  SPACE: "space";
@@ -1 +1 @@
1
- {"version":3,"file":"indent.d.ts","sourceRoot":"","sources":["../../lib/rules/indent.js"],"names":[],"mappings":";;;wBAgCU,UAAU;;kBA/BN,OAAO,UAAU,EAAE,UAAU;eAC7B,OAAO,UAAU,EAAE,OAAO;gBAC1B,OAAO,UAAU,EAAE,QAAQ;gBAC3B,OAAO,UAAU,EAAE,QAAQ;eAC3B,OAAO,UAAU,EAAE,OAAO;;SAE1B,KAAK;WACL,OAAO;;;kBAEP,aAAa"}
1
+ {"version":3,"file":"indent.d.ts","sourceRoot":"","sources":["../../lib/rules/indent.js"],"names":[],"mappings":";;;wBAwCU,UAAU;;kBAvCN,OAAO,UAAU,EAAE,UAAU;eAC7B,OAAO,UAAU,EAAE,OAAO;gBAC1B,OAAO,UAAU,EAAE,QAAQ;gBAC3B,OAAO,UAAU,EAAE,QAAQ;eAC3B,OAAO,UAAU,EAAE,OAAO;oBAC1B,OAAO,UAAU,EAAE,YAAY;aAC/B,OAAO,QAAQ,EAAE,GAAG,CAAC,KAAK;kBAC1B,OAAO,QAAQ,EAAE,UAAU;uBAC3B,OAAO,QAAQ,EAAE,eAAe;;SAEhC,KAAK;WACL,OAAO;;;kBAEP,aAAa"}