Skip to content

Commit 1b64d63

Browse files
Adds a new rule htmlacademy/req-tags-presence (#108)
* Adds a new rule htmlacademy/req-tags-presence * Adds a description for the rule * Adds a rule to the general list * Update CHANGELOG.md * Remove trash text
1 parent 55d9da3 commit 1b64d63

File tree

4 files changed

+99
-6
lines changed

4 files changed

+99
-6
lines changed

CHANGELOG.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 1.0.20
4+
Adds a `req-tags-presence` rule that requires the specified tags on the page.
5+
6+
```json
7+
{
8+
"htmlacademy/req-tags-presence": [ true, ["header", "nav", "main", "section", "h1", "footer"]]
9+
}
10+
```
11+
312
## 1.0.19
413
Adds a `tag-forbid-attr` rule that disallows the use of specified attributes on the specified tag.
514

@@ -84,11 +93,11 @@ Added a new rule [htmlacademy/req-stylesheet-link](rules/req-stylesheet-link/REA
8493
- Excludes the `<input type="submit">` check from the [input-req-label](rules/input-req-label/README.md) rule.
8594
- Adds `ignore` option for [tag-req-attr](rules/tag-req-attr/README.md)
8695
```js
87-
'input': [
96+
"input": [
8897
{
89-
name: 'name',
98+
name: "name",
9099
ignore: {
91-
'type': 'submit'
100+
"type": "submit"
92101
}
93102
},
94103
],
@@ -118,7 +127,7 @@ The following pattern is **not** considered a problem:
118127
Added [htmlacademy/space-between-comments](rules/space-between-comments/README.md)
119128
```js
120129
rules: {
121-
'htmlacademy/space-between-comments': [true, 'space' | 'no-space]
130+
"htmlacademy/space-between-comments": [true, "space" | "no-space]
122131
}
123132
```
124133
@@ -159,7 +168,7 @@ Adds new rule `htmlacademy/attr-req-value`: the attribute cannot be empty, excep
159168
160169
```js
161170
{
162-
'htmlacademy/attr-req-value': [true, { ignore: ['alt']}]
171+
"htmlacademy/attr-req-value": [true, { ignore: ["alt"]}]
163172
}
164173
```
165174

docs/list-of-rules.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@
2424
| [htmlacademy/req-mailto](../rules/req-mailto/README.md) | Требует `mailto:` для ссылок c email-текстом |
2525
| [htmlacademy/req-meta-viewport](../rules/req-meta-viewport/README.md) | Проверяет наличие `<meta name="viewport" content="width=device-width,initial-scale=1">` в `<head>` |
2626
| [htmlacademy/req-single-styles](../rules/req-single-styles/README.md) | Разрешает не более одного `link rel="stylesheet"` в `<head>` |
27-
| [htmlacademy/req-source-width-height](../rules/req-source-width-height/README.md) | Требует `width` и `height` у `<source>` внутри `<picture>` |
27+
| [htmlacademy/req-source-width-height](../rules/req-source-width-height/README.md) | Требует `width` и `height` у `<source>` внутри `<picture>` |
2828
| [htmlacademy/req-stylesheet-link](../rules/req-stylesheet-link/README.md) | Проверяет наличие `<link rel="stylesheet" href="">` с непустым `href` |
29+
| [htmlacademy/req-tags-presence](../rules/req-tags-presence/README.md) | Требует указанные теги на странице |
2930
| [htmlacademy/section-has-heading](../rules/section-has-heading/README.md) | Требует добавление заголовка любого уровня в `<section>` |
3031
| [htmlacademy/space-between-comments](../rules/space-between-comments/README.md) | Проверят пробелы у комментария `<!-- Это комментарий -->` |
3132
| [htmlacademy/tag-forbid-attr](../rules/tag-forbid-attr/README.md) | Указанные атрибуты должны отсутствовать в указанном теге |

rules/req-tags-presence/README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# htmlacademy/req-tags-presence
2+
3+
Если установлено, указанные теги должны находится на странице. Если теги отсутствуют, правило считается нарушенным.
4+
5+
## true
6+
7+
В массив можно передать любые теги. Если хотя бы один из них отсутствует, правило считается нарушенным.
8+
9+
10+
```json
11+
{
12+
"htmlacademy/req-tags-presence": [true, ["h1", "main"]]
13+
}
14+
```
15+
16+
Нарушениями считаются следующие модели:
17+
18+
Потому что без тега `<h1>` и `<main>`.
19+
20+
```html
21+
<body>
22+
<div></div>
23+
<div></div>
24+
<div></div>
25+
</body>
26+
```
27+
28+
Потому что без тега `<h1>`.
29+
30+
```html
31+
<body>
32+
<header></header>
33+
<main></main>
34+
<footer></footer>
35+
</body>
36+
```
37+
38+
Следующие детали **не** считаются нарушениями:
39+
40+
```html
41+
<body>
42+
<main>
43+
<h1></h1>
44+
</main>
45+
</body>
46+
```

rules/req-tags-presence/index.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict';
2+
const { is_tag_node } = require('@linthtml/dom-utils');
3+
4+
const traverseNode = (node, remainingTags) => {
5+
if (is_tag_node(node)) {
6+
remainingTags.delete(node.name);
7+
}
8+
if (node.children) {
9+
for (const child of node.children) {
10+
traverseNode(child, remainingTags);
11+
}
12+
}
13+
};
14+
15+
const findMissingTags = (node, remainingTags) => {
16+
traverseNode(node, remainingTags);
17+
return remainingTags;
18+
};
19+
20+
module.exports = {
21+
name: 'htmlacademy/req-tags-presence',
22+
// eslint-disable-next-line camelcase
23+
lint(node, rule_config, { report }) {
24+
if (is_tag_node(node) && node.name.toLowerCase() === 'html') {
25+
const missingTags = findMissingTags(node, new Set(rule_config));
26+
if (missingTags.size > 0) {
27+
report({
28+
position: {
29+
start: { line: 1, column: 1 },
30+
end: { line: 1, column: 1 },
31+
},
32+
message: `The page is missing the following tags: ${Array.from(missingTags).join(', ')}.`,
33+
});
34+
}
35+
}
36+
},
37+
};

0 commit comments

Comments
 (0)