Skip to content

Commit d96a632

Browse files
Adds a new rule req-preload-font (#109)
* Adds a new rule req-preload-font * Adds a description of the rule * Adds a rule to the list * Update CHANGELOG.md * Fix eslint
1 parent 1b64d63 commit d96a632

File tree

4 files changed

+105
-35
lines changed

4 files changed

+105
-35
lines changed

CHANGELOG.md

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

33
## 1.0.20
4-
Adds a `req-tags-presence` rule that requires the specified tags on the page.
4+
- Adds a `req-tags-presence` rule that requires the specified tags on the page.
5+
- Adds a `req-preload-font` rule that requires the `preload` value for the font.
6+
57

68
```json
79
{
8-
"htmlacademy/req-tags-presence": [ true, ["header", "nav", "main", "section", "h1", "footer"]]
10+
"htmlacademy/req-tags-presence": [ true, ["header", "nav", "main", "section", "h1", "footer"]],
11+
"htmlacademy/req-preload-font": true
912
}
1013
```
1114

docs/list-of-rules.md

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,36 @@
11
# Список правил от HTML Academy
22

3-
| Имя правила | Описания |
4-
|-------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|
5-
| [htmlacademy/a-target-rel](../rules/a-target-rel/README.md) | Проверяет наличие `rel="noopener noreferrer"` у `<a target="_blank"></a>` |
6-
| [htmlacademy/aria-label-misuse](../rules/aria-label-misuse/README.md) | Требует использование `aria-label` на определённых элементах |
7-
| [htmlacademy/attr-delimiter](../rules/attr-delimiter/README.md) | Требует удалить пробел между `=` для атрибутов |
8-
| [htmlacademy/attr-req-value](../rules/attr-req-value/README.md) | Запрещает пустые атрибуты `""`, кроме тех что в `ignore: []` |
9-
| [htmlacademy/attribute-allowed-values](../rules/attribute-allowed-values/README.md) | Проверяет атрибуты на наличие допустимых значений |
10-
| [htmlacademy/ban-url-spaces](../rules/ban-url-spaces/README.md) | Проверяет наличие пробелов в адресах в атрибутах `href` и `src`. |
11-
| [htmlacademy/charset-position](../rules/charset-position/README.md) | Требует указывать `<meta charset="utf-8">` первым элементов в `<head>` |
12-
| [htmlacademy/class-first](../rules/class-first/README.md) | Требует указывать первым атрибутом у любого элемента `class` |
13-
| [htmlacademy/form-action-attribute](../rules/form-action-attribute/README.md) | Требует указывать атрибут `action` у `<form>` |
14-
| [htmlacademy/head-meta-charset](../rules/head-meta-charset/README.md) | Проверяет наличие `<meta charset="utf-8">` в `<head>` |
15-
| [htmlacademy/id-no-dup](../rules/id-no-dup/README.md) | Запрешает дублирование `id` на странице |
16-
| [htmlacademy/img-svg-req-dimensions](../rules/img-svg-req-dimensions/README.md) | Требует атрибуты `width` и `height` у `<img>` и `<svg>` |
17-
| [htmlacademy/input-req-label](../rules/input-req-label/README.md) | Требует наличие метки для поля ввода, и позволяет указать метку в `aria-label` |
18-
| [htmlacademy/link-req-content](../rules/link-req-content/README.md) | Проверяет наличие текстового содержания у `<a>` |
19-
| [htmlacademy/no-blocking-script](../rules/no-blocking-script/README.md) | Проверяет расположение скриптов в разметке |
20-
| [htmlacademy/no-double-br](../rules/no-double-br/README.md) | Запрещает идущие подряд двойной `<br>` |
21-
| [htmlacademy/no-px-size](../rules/no-px-size/README.md) | Атрибуты `width` и `height` содержат только цифры, без единиц измерения |
22-
| [htmlacademy/req-charset-utf](../rules/req-charset-utf/README.md) | Требует `UTF-8` для `<meta charset="">` |
23-
| [htmlacademy/req-head-styles](../rules/req-head-styles/README.md) | Запрещает подключение стилей вне `<head>` |
24-
| [htmlacademy/req-mailto](../rules/req-mailto/README.md) | Требует `mailto:` для ссылок c email-текстом |
25-
| [htmlacademy/req-meta-viewport](../rules/req-meta-viewport/README.md) | Проверяет наличие `<meta name="viewport" content="width=device-width,initial-scale=1">` в `<head>` |
26-
| [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>` |
28-
| [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) | Требует указанные теги на странице |
30-
| [htmlacademy/section-has-heading](../rules/section-has-heading/README.md) | Требует добавление заголовка любого уровня в `<section>` |
31-
| [htmlacademy/space-between-comments](../rules/space-between-comments/README.md) | Проверят пробелы у комментария `<!-- Это комментарий -->` |
32-
| [htmlacademy/tag-forbid-attr](../rules/tag-forbid-attr/README.md) | Указанные атрибуты должны отсутствовать в указанном теге |
33-
| [htmlacademy/tag-name-lowercase](../rules/tag-name-lowercase/README.md) | Имена тегов должны быть строчными |
34-
| [htmlacademy/tag-req-attr](../rules/tag-req-attr/README.md) | Указанные атрибуты должны присутствовать в указанном теге |
35-
| [htmlacademy/tag-self-close](../rules/tag-self-close/README.md) | Одиночные элементы не должны быть закрыты, `<br>` вместо `<br/>` |
3+
| Имя правила | Описания |
4+
|------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
5+
| [htmlacademy/a-target-rel](../rules/a-target-rel/README.md) | Проверяет наличие `rel="noopener noreferrer"` у `<a target="_blank"></a>` |
6+
| [htmlacademy/aria-label-misuse](../rules/aria-label-misuse/README.md) | Требует использование `aria-label` на определённых элементах |
7+
| [htmlacademy/attr-delimiter](../rules/attr-delimiter/README.md) | Требует удалить пробел между `=` для атрибутов |
8+
| [htmlacademy/attr-req-value](../rules/attr-req-value/README.md) | Запрещает пустые атрибуты `""`, кроме тех что в `ignore: []` |
9+
| [htmlacademy/attribute-allowed-values](../rules/attribute-allowed-values/README.md) | Проверяет атрибуты на наличие допустимых значений |
10+
| [htmlacademy/ban-url-spaces](../rules/ban-url-spaces/README.md) | Проверяет наличие пробелов в адресах в атрибутах `href` и `src`. |
11+
| [htmlacademy/charset-position](../rules/charset-position/README.md) | Требует указывать `<meta charset="utf-8">` первым элементов в `<head>` |
12+
| [htmlacademy/class-first](../rules/class-first/README.md) | Требует указывать первым атрибутом у любого элемента `class` |
13+
| [htmlacademy/form-action-attribute](../rules/form-action-attribute/README.md) | Требует указывать атрибут `action` у `<form>` |
14+
| [htmlacademy/head-meta-charset](../rules/head-meta-charset/README.md) | Проверяет наличие `<meta charset="utf-8">` в `<head>` |
15+
| [htmlacademy/id-no-dup](../rules/id-no-dup/README.md) | Запрешает дублирование `id` на странице |
16+
| [htmlacademy/img-svg-req-dimensions](../rules/img-svg-req-dimensions/README.md) | Требует атрибуты `width` и `height` у `<img>` и `<svg>` |
17+
| [htmlacademy/input-req-label](../rules/input-req-label/README.md) | Требует наличие метки для поля ввода, и позволяет указать метку в `aria-label` |
18+
| [htmlacademy/link-req-content](../rules/link-req-content/README.md) | Проверяет наличие текстового содержания у `<a>` |
19+
| [htmlacademy/no-blocking-script](../rules/no-blocking-script/README.md) | Проверяет расположение скриптов в разметке |
20+
| [htmlacademy/no-double-br](../rules/no-double-br/README.md) | Запрещает идущие подряд двойной `<br>` |
21+
| [htmlacademy/no-px-size](../rules/no-px-size/README.md) | Атрибуты `width` и `height` содержат только цифры, без единиц измерения |
22+
| [htmlacademy/req-charset-utf](../rules/req-charset-utf/README.md) | Требует `UTF-8` для `<meta charset="">` |
23+
| [htmlacademy/req-head-styles](../rules/req-head-styles/README.md) | Запрещает подключение стилей вне `<head>` |
24+
| [htmlacademy/req-mailto](../rules/req-mailto/README.md) | Требует `mailto:` для ссылок c email-текстом |
25+
| [htmlacademy/req-meta-viewport](../rules/req-meta-viewport/README.md) | Проверяет наличие `<meta name="viewport" content="width=device-width,initial-scale=1">` в `<head>` |
26+
| [htmlacademy/req-preload-font](../rules/req-preload-font/README.md) | Проверяет наличие предзагрузки шрифта в `<head>` |
27+
| [htmlacademy/req-single-styles](../rules/req-single-styles/README.md) | Разрешает не более одного `link rel="stylesheet"` в `<head>` |
28+
| [htmlacademy/req-source-width-height](../rules/req-source-width-height/README.md) | Требует `width` и `height` у `<source>` внутри `<picture>` |
29+
| [htmlacademy/req-stylesheet-link](../rules/req-stylesheet-link/README.md) | Проверяет наличие `<link rel="stylesheet" href="">` с непустым `href` |
30+
| [htmlacademy/req-tags-presence](../rules/req-tags-presence/README.md) | Требует указанные теги на странице |
31+
| [htmlacademy/section-has-heading](../rules/section-has-heading/README.md) | Требует добавление заголовка любого уровня в `<section>` |
32+
| [htmlacademy/space-between-comments](../rules/space-between-comments/README.md) | Проверят пробелы у комментария `<!-- Это комментарий -->` |
33+
| [htmlacademy/tag-forbid-attr](../rules/tag-forbid-attr/README.md) | Указанные атрибуты должны отсутствовать в указанном теге |
34+
| [htmlacademy/tag-name-lowercase](../rules/tag-name-lowercase/README.md) | Имена тегов должны быть строчными |
35+
| [htmlacademy/tag-req-attr](../rules/tag-req-attr/README.md) | Указанные атрибуты должны присутствовать в указанном теге |
36+
| [htmlacademy/tag-self-close](../rules/tag-self-close/README.md) | Одиночные элементы не должны быть закрыты, `<br>` вместо `<br/>` |

rules/req-preload-font/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# htmlacademy/req-preload-font
2+
3+
Правило проверяет наличие значение `preload` для шрифта.
4+
5+
## true
6+
В `<head>` должна быть указана предзагрузка шрифтов
7+
8+
```html
9+
<head>
10+
<link rel="preload" href="path/to/font.font" as="font" type="font/*" crossorigin="anonymous">
11+
</head>
12+
```
13+
14+
`*` - тип шрифта
15+
`path/to/font.font` - путь до шрифта
16+
17+
18+
Проблемными считаются следующие шаблоны:
19+
20+
Без `preload`:
21+
```html
22+
<head>
23+
24+
</head>
25+
```
26+
27+
С пустым или отсутствующим href:
28+
```html
29+
<head>
30+
<link rel="preload" href="" type="font/woff2" as="font">
31+
</head>
32+
```
33+
34+
Следующие шаблоны **не** считаются проблемами:
35+
```html
36+
<head>
37+
<link rel="preload" href="path/to/font.woff2" as="font" type="font/woff2">
38+
</head>
39+
```
40+

rules/req-preload-font/index.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use strict';
2+
const { has_non_empty_attribute, is_tag_node, attribute_has_value } = require('@linthtml/dom-utils');
3+
4+
module.exports = {
5+
name: 'htmlacademy/req-preload-font',
6+
// eslint-disable-next-line camelcase
7+
lint(node, rule_config, { report }) {
8+
if (is_tag_node(node) && node.name === 'head') {
9+
const hasRequiredPreload = node.children.some((child) =>
10+
is_tag_node(child) &&
11+
child.name === 'link' &&
12+
attribute_has_value(child, 'rel', 'preload') &&
13+
has_non_empty_attribute(child, 'href') &&
14+
attribute_has_value(child, 'type', /^font\//i) &&
15+
attribute_has_value(child, 'as', 'font')
16+
);
17+
18+
if (!hasRequiredPreload) {
19+
report({
20+
position: node.loc,
21+
message: 'The head tag should contain a link tag with rel="preload", type="font/woff2", and as="font".',
22+
});
23+
}
24+
}
25+
}
26+
};

0 commit comments

Comments
 (0)