@markuplint/rules 3.1.0 → 3.2.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.
- package/lib/__foo/index.d.ts +2 -0
- package/lib/__foo/index.js +32 -0
- package/lib/attr-check.js +6 -0
- package/lib/index.js +2 -0
- package/lib/placeholder-label-option/index.js +48 -12
- package/package.json +6 -6
- package/schema.json +3 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ml_core_1 = require("@markuplint/ml-core");
|
|
4
|
+
exports.default = (0, ml_core_1.createRule)({
|
|
5
|
+
defaultValue: true,
|
|
6
|
+
defaultOptions: null,
|
|
7
|
+
async verify({ document, report, t }) {
|
|
8
|
+
// Element
|
|
9
|
+
await document.walkOn("Element", (el) => {
|
|
10
|
+
const raw = el.raw.trim();
|
|
11
|
+
if (/./i.test(raw)) {
|
|
12
|
+
report({
|
|
13
|
+
scope: el,
|
|
14
|
+
message: t("It is {0}", "issue"),
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
// Attribute
|
|
19
|
+
await document.walkOn("Attr", (attr) => {
|
|
20
|
+
var _a, _b, _c;
|
|
21
|
+
if (/./i.test(attr.name)) {
|
|
22
|
+
report({
|
|
23
|
+
scope: attr,
|
|
24
|
+
line: (_a = attr.nameNode) === null || _a === void 0 ? void 0 : _a.startLine,
|
|
25
|
+
col: (_b = attr.nameNode) === null || _b === void 0 ? void 0 : _b.startCol,
|
|
26
|
+
raw: (_c = attr.nameNode) === null || _c === void 0 ? void 0 : _c.raw,
|
|
27
|
+
message: t("It is {0}", "issue"),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
});
|
package/lib/attr-check.js
CHANGED
|
@@ -22,6 +22,12 @@ function attrCheck(t, name, value, isCustomRule, spec) {
|
|
|
22
22
|
// Ignore checking because ARIA attributes are check on another rule
|
|
23
23
|
return false;
|
|
24
24
|
}
|
|
25
|
+
// @see https://www.w3.org/TR/adapt/
|
|
26
|
+
// It is an experimental
|
|
27
|
+
if (/^adapt-.+$/.test(name)) {
|
|
28
|
+
// Ignore checking because "adapt-*" attribute is any type
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
25
31
|
}
|
|
26
32
|
// Existence
|
|
27
33
|
if (!spec) {
|
package/lib/index.js
CHANGED
|
@@ -24,6 +24,7 @@ const no_hard_code_id_1 = tslib_1.__importDefault(require("./no-hard-code-id"));
|
|
|
24
24
|
const no_refer_to_non_existent_id_1 = tslib_1.__importDefault(require("./no-refer-to-non-existent-id"));
|
|
25
25
|
const no_use_event_handler_attr_1 = tslib_1.__importDefault(require("./no-use-event-handler-attr"));
|
|
26
26
|
const permitted_contents_1 = tslib_1.__importDefault(require("./permitted-contents"));
|
|
27
|
+
const placeholder_label_option_1 = tslib_1.__importDefault(require("./placeholder-label-option"));
|
|
27
28
|
const require_accessible_name_1 = tslib_1.__importDefault(require("./require-accessible-name"));
|
|
28
29
|
const require_datetime_1 = tslib_1.__importDefault(require("./require-datetime"));
|
|
29
30
|
const required_attr_1 = tslib_1.__importDefault(require("./required-attr"));
|
|
@@ -55,6 +56,7 @@ exports.default = {
|
|
|
55
56
|
'no-refer-to-non-existent-id': no_refer_to_non_existent_id_1.default,
|
|
56
57
|
'no-use-event-handler-attr': no_use_event_handler_attr_1.default,
|
|
57
58
|
'permitted-contents': permitted_contents_1.default,
|
|
59
|
+
'placeholder-label-option': placeholder_label_option_1.default,
|
|
58
60
|
'require-accessible-name': require_accessible_name_1.default,
|
|
59
61
|
'require-datetime': require_datetime_1.default,
|
|
60
62
|
'required-attr': required_attr_1.default,
|
|
@@ -4,41 +4,77 @@ const ml_core_1 = require("@markuplint/ml-core");
|
|
|
4
4
|
exports.default = (0, ml_core_1.createRule)({
|
|
5
5
|
verify({ document, report, t }) {
|
|
6
6
|
document.querySelectorAll('select').forEach(select => {
|
|
7
|
-
|
|
8
|
-
if (!required) {
|
|
7
|
+
if (hasPlaceholderLabelOption(select)) {
|
|
9
8
|
return;
|
|
10
9
|
}
|
|
11
|
-
if (!
|
|
12
|
-
|
|
13
|
-
scope: required,
|
|
14
|
-
message: t('{0} if it has {1}', t('need {0}', t('the {0}', 'placeholder label option')), t('the "{0*}" {1}', 'required', 'attribute')),
|
|
15
|
-
});
|
|
10
|
+
if (!needPlaceholderLabelOption(select)) {
|
|
11
|
+
return;
|
|
16
12
|
}
|
|
13
|
+
report({
|
|
14
|
+
scope: select,
|
|
15
|
+
message: t('need {0}', t('the {0}', 'placeholder label option')),
|
|
16
|
+
});
|
|
17
17
|
});
|
|
18
18
|
},
|
|
19
19
|
});
|
|
20
|
+
/**
|
|
21
|
+
* > If a select element has a required attribute specified,
|
|
22
|
+
* > does not have a multiple attribute specified,
|
|
23
|
+
* > and has a display size of 1,
|
|
24
|
+
* > then the select element must have a placeholder label option.
|
|
25
|
+
*
|
|
26
|
+
* @param select
|
|
27
|
+
* @returns
|
|
28
|
+
*/
|
|
29
|
+
function needPlaceholderLabelOption(select) {
|
|
30
|
+
const hasRequired = select.hasAttribute('required');
|
|
31
|
+
if (!hasRequired) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
const hasMultiple = select.hasAttribute('multiple');
|
|
35
|
+
if (hasMultiple) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const size = select.getAttribute('size') || '1';
|
|
39
|
+
if (size !== '1') {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* > If a select element has a required attribute specified,
|
|
46
|
+
* > does not have a multiple attribute specified,
|
|
47
|
+
* > and has a display size of 1;
|
|
48
|
+
* > and if the value of the first option element
|
|
49
|
+
* > in the select element's list of options (if any) is the empty string,
|
|
50
|
+
* > and that option element's parent node is the select element (and not an optgroup element),
|
|
51
|
+
* > then that option is the select element's **placeholder label option**.
|
|
52
|
+
*
|
|
53
|
+
* @param select
|
|
54
|
+
* @returns
|
|
55
|
+
*/
|
|
20
56
|
function hasPlaceholderLabelOption(select) {
|
|
21
57
|
var _a;
|
|
22
|
-
// has a required attribute specified
|
|
58
|
+
// > has a required attribute specified
|
|
23
59
|
if (!select.hasAttribute('required')) {
|
|
24
60
|
return false;
|
|
25
61
|
}
|
|
26
|
-
// does not have a multiple attribute specified
|
|
62
|
+
// > does not have a multiple attribute specified
|
|
27
63
|
if (select.hasAttribute('multiple')) {
|
|
28
64
|
return false;
|
|
29
65
|
}
|
|
30
|
-
// has a display size of 1
|
|
66
|
+
// > has a display size of 1
|
|
31
67
|
const size = select.getAttribute('size') || '1';
|
|
32
68
|
if (size !== '1') {
|
|
33
69
|
return false;
|
|
34
70
|
}
|
|
35
|
-
// in the select element's list of options (if any) is the empty string
|
|
71
|
+
// > in the select element's list of options (if any) is the empty string
|
|
36
72
|
const firstOption = select.querySelector('option');
|
|
37
73
|
if (!firstOption) {
|
|
38
74
|
// if any
|
|
39
75
|
return true;
|
|
40
76
|
}
|
|
41
|
-
// that option element's parent node is the select element (and not an optgroup element)
|
|
77
|
+
// > that option element's parent node is the select element (and not an optgroup element)
|
|
42
78
|
if (((_a = firstOption.parentElement) === null || _a === void 0 ? void 0 : _a.localName) === 'optgroup') {
|
|
43
79
|
return false;
|
|
44
80
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/rules",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Built-in rules of markuplint",
|
|
5
5
|
"repository": "git@github.com:markuplint/markuplint.git",
|
|
6
6
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
"./lib/permitted-contents/debug.js": "./lib/permitted-contents/debug.browser.js"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@markuplint/html-spec": "3.
|
|
24
|
-
"@markuplint/ml-core": "3.
|
|
25
|
-
"@markuplint/ml-spec": "3.
|
|
26
|
-
"@markuplint/types": "3.
|
|
23
|
+
"@markuplint/html-spec": "3.2.0",
|
|
24
|
+
"@markuplint/ml-core": "3.2.0",
|
|
25
|
+
"@markuplint/ml-spec": "3.2.0",
|
|
26
|
+
"@markuplint/types": "3.1.0",
|
|
27
27
|
"@ungap/structured-clone": "^1.0.1",
|
|
28
28
|
"chrono-node": "^2.5.0",
|
|
29
29
|
"debug": "^4.3.4",
|
|
@@ -33,5 +33,5 @@
|
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/debug": "^4.1.7"
|
|
35
35
|
},
|
|
36
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "26b04e045d91e29befca34c10dda2147b1bca9c7"
|
|
37
37
|
}
|
package/schema.json
CHANGED
|
@@ -75,6 +75,9 @@
|
|
|
75
75
|
"permitted-contents": {
|
|
76
76
|
"$ref": "https://raw.githubusercontent.com/markuplint/markuplint/main/packages/%40markuplint/rules/src/permitted-contents/schema.json"
|
|
77
77
|
},
|
|
78
|
+
"placeholder-label-option": {
|
|
79
|
+
"$ref": "https://raw.githubusercontent.com/markuplint/markuplint/main/packages/%40markuplint/rules/src/placeholder-label-option/schema.json"
|
|
80
|
+
},
|
|
78
81
|
"require-accessible-name": {
|
|
79
82
|
"$ref": "https://raw.githubusercontent.com/markuplint/markuplint/main/packages/%40markuplint/rules/src/require-accessible-name/schema.json"
|
|
80
83
|
},
|