@markuplint/rules 3.0.0-dev.25 → 3.0.0-dev.300
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/attr-check.d.ts +3 -2
- package/lib/attr-check.js +42 -38
- package/lib/attr-duplication/index.d.ts +1 -1
- package/lib/attr-duplication/index.js +3 -5
- package/lib/attr-value-quotes/index.d.ts +1 -1
- package/lib/attr-value-quotes/index.js +5 -9
- package/lib/case-sensitive-attr-name/index.d.ts +1 -1
- package/lib/case-sensitive-attr-name/index.js +9 -13
- package/lib/case-sensitive-tag-name/index.d.ts +1 -1
- package/lib/case-sensitive-tag-name/index.js +2 -4
- package/lib/character-reference/index.d.ts +1 -1
- package/lib/character-reference/index.js +7 -9
- package/lib/class-naming/index.d.ts +1 -1
- package/lib/class-naming/index.js +9 -13
- package/lib/create-message.d.ts +3 -2
- package/lib/create-message.js +15 -17
- package/lib/debug.js +2 -6
- package/lib/deprecated-attr/index.d.ts +1 -1
- package/lib/deprecated-attr/index.js +6 -9
- package/lib/deprecated-element/index.d.ts +1 -1
- package/lib/deprecated-element/index.js +5 -7
- package/lib/disallowed-element/index.d.ts +1 -1
- package/lib/disallowed-element/index.js +2 -4
- package/lib/doctype/index.d.ts +1 -1
- package/lib/doctype/index.js +2 -4
- package/lib/end-tag/index.d.ts +1 -1
- package/lib/end-tag/index.js +5 -8
- package/lib/helpers.d.ts +10 -13
- package/lib/helpers.js +39 -37
- package/lib/id-duplication/index.d.ts +1 -1
- package/lib/id-duplication/index.js +2 -4
- package/lib/index.d.ts +102 -3
- package/lib/index.js +64 -62
- package/lib/ineffective-attr/index.d.ts +1 -1
- package/lib/ineffective-attr/index.js +5 -10
- package/lib/invalid-attr/index.d.ts +25 -5
- package/lib/invalid-attr/index.js +166 -43
- package/lib/label-has-control/index.d.ts +1 -1
- package/lib/label-has-control/index.js +2 -4
- package/lib/landmark-roles/index.d.ts +1 -1
- package/lib/landmark-roles/index.js +10 -9
- package/lib/no-boolean-attr-value/index.d.ts +1 -1
- package/lib/no-boolean-attr-value/index.js +6 -9
- package/lib/no-default-value/index.d.ts +1 -1
- package/lib/no-default-value/index.js +9 -12
- package/lib/no-empty-palpable-content/index.d.ts +1 -1
- package/lib/no-empty-palpable-content/index.js +13 -7
- package/lib/no-hard-code-id/index.d.ts +1 -1
- package/lib/no-hard-code-id/index.js +2 -4
- package/lib/no-refer-to-non-existent-id/index.d.ts +4 -4
- package/lib/no-refer-to-non-existent-id/index.js +79 -23
- package/lib/no-use-event-handler-attr/index.d.ts +1 -1
- package/lib/no-use-event-handler-attr/index.js +4 -6
- package/lib/permitted-contents/choice.d.ts +3 -2
- package/lib/permitted-contents/choice.js +54 -14
- package/lib/permitted-contents/complex-branch.d.ts +3 -2
- package/lib/permitted-contents/complex-branch.js +12 -14
- package/lib/permitted-contents/content-model.d.ts +2 -2
- package/lib/permitted-contents/content-model.js +11 -11
- package/lib/permitted-contents/count-pattern.d.ts +3 -2
- package/lib/permitted-contents/count-pattern.js +76 -74
- package/lib/permitted-contents/debug.browser.js +9 -12
- package/lib/permitted-contents/debug.d.ts +8 -1
- package/lib/permitted-contents/debug.js +12 -13
- package/lib/permitted-contents/index.d.ts +2 -2
- package/lib/permitted-contents/index.js +18 -24
- package/lib/permitted-contents/matches-selector.d.ts +2 -2
- package/lib/permitted-contents/matches-selector.js +17 -20
- package/lib/permitted-contents/order.d.ts +3 -2
- package/lib/permitted-contents/order.js +33 -28
- package/lib/permitted-contents/recursive-branch.d.ts +4 -3
- package/lib/permitted-contents/recursive-branch.js +11 -13
- package/lib/permitted-contents/represent-transparent-nodes.d.ts +1 -1
- package/lib/permitted-contents/represent-transparent-nodes.js +18 -21
- package/lib/permitted-contents/start.d.ts +3 -2
- package/lib/permitted-contents/start.js +16 -22
- package/lib/permitted-contents/transparent.d.ts +2 -2
- package/lib/permitted-contents/transparent.js +6 -9
- package/lib/permitted-contents/types.d.ts +20 -13
- package/lib/permitted-contents/types.js +1 -2
- package/lib/permitted-contents/utils.d.ts +27 -8
- package/lib/permitted-contents/utils.js +164 -65
- package/lib/placeholder-label-option/index.d.ts +2 -0
- package/lib/placeholder-label-option/index.js +84 -0
- package/lib/require-accessible-name/index.d.ts +1 -1
- package/lib/require-accessible-name/index.js +10 -13
- package/lib/require-datetime/index.d.ts +6 -0
- package/lib/require-datetime/index.js +32 -0
- package/lib/require-datetime/types.d.ts +10 -0
- package/lib/require-datetime/types.js +1 -0
- package/lib/require-datetime/utils.d.ts +11 -0
- package/lib/require-datetime/utils.js +130 -0
- package/lib/required-attr/index.d.ts +2 -2
- package/lib/required-attr/index.js +24 -24
- package/lib/required-element/index.d.ts +1 -1
- package/lib/required-element/index.js +3 -5
- package/lib/required-h1/index.d.ts +1 -1
- package/lib/required-h1/index.js +4 -6
- package/lib/use-list/index.d.ts +2 -2
- package/lib/use-list/index.js +7 -9
- package/lib/wai-aria/checkings/abstract-role.d.ts +1 -1
- package/lib/wai-aria/checkings/abstract-role.js +5 -10
- package/lib/wai-aria/checkings/default-value.d.ts +2 -2
- package/lib/wai-aria/checkings/default-value.js +2 -6
- package/lib/wai-aria/checkings/deprecated-props.d.ts +2 -2
- package/lib/wai-aria/checkings/deprecated-props.js +3 -8
- package/lib/wai-aria/checkings/disallowed-prop.d.ts +2 -2
- package/lib/wai-aria/checkings/disallowed-prop.js +27 -8
- package/lib/wai-aria/checkings/implicit-props.d.ts +3 -3
- package/lib/wai-aria/checkings/implicit-props.js +7 -11
- package/lib/wai-aria/checkings/implicit-role.d.ts +1 -1
- package/lib/wai-aria/checkings/implicit-role.js +4 -9
- package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +1 -1
- package/lib/wai-aria/checkings/interaction-in-hidden.js +7 -9
- package/lib/wai-aria/checkings/no-global-prop.d.ts +2 -2
- package/lib/wai-aria/checkings/no-global-prop.js +2 -7
- package/lib/wai-aria/checkings/non-existent-role.d.ts +1 -1
- package/lib/wai-aria/checkings/non-existent-role.js +4 -9
- package/lib/wai-aria/checkings/permitted-roles.d.ts +1 -1
- package/lib/wai-aria/checkings/permitted-roles.js +4 -9
- package/lib/wai-aria/checkings/presentational-children.d.ts +1 -1
- package/lib/wai-aria/checkings/presentational-children.js +7 -10
- package/lib/wai-aria/checkings/required-owned-elements.d.ts +1 -1
- package/lib/wai-aria/checkings/required-owned-elements.js +10 -12
- package/lib/wai-aria/checkings/required-prop.d.ts +2 -2
- package/lib/wai-aria/checkings/required-prop.js +2 -7
- package/lib/wai-aria/checkings/value.d.ts +3 -3
- package/lib/wai-aria/checkings/value.js +7 -11
- package/lib/wai-aria/index.d.ts +2 -2
- package/lib/wai-aria/index.js +38 -39
- package/lib/wai-aria/types.js +1 -2
- package/package.json +21 -14
- package/schema.json +6 -0
- package/tsconfig.test.json +0 -3
- package/tsconfig.tsbuildinfo +0 -1
package/lib/end-tag/index.js
CHANGED
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const ml_spec_1 = require("@markuplint/ml-spec");
|
|
5
|
-
exports.default = (0, ml_core_1.createRule)({
|
|
1
|
+
import { createRule } from '@markuplint/ml-core';
|
|
2
|
+
import { isVoidElement } from '@markuplint/ml-spec';
|
|
3
|
+
export default createRule({
|
|
6
4
|
defaultSeverity: 'warning',
|
|
7
5
|
async verify({ document, report, t }) {
|
|
8
6
|
if (document.endTag === 'never') {
|
|
9
7
|
return;
|
|
10
8
|
}
|
|
11
9
|
await document.walkOn('Element', el => {
|
|
12
|
-
var _a;
|
|
13
10
|
if (el.isOmitted) {
|
|
14
11
|
return;
|
|
15
12
|
}
|
|
16
|
-
if (
|
|
13
|
+
if (isVoidElement(el)) {
|
|
17
14
|
return;
|
|
18
15
|
}
|
|
19
16
|
if (el.closeTag != null) {
|
|
20
17
|
return;
|
|
21
18
|
}
|
|
22
|
-
if ((document.endTag === 'xml' || el.isForeignElement) &&
|
|
19
|
+
if ((document.endTag === 'xml' || el.isForeignElement) && el.selfClosingSolidus?.raw) {
|
|
23
20
|
return;
|
|
24
21
|
}
|
|
25
22
|
report({
|
package/lib/helpers.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type { Log } from './debug';
|
|
1
|
+
import type { Log } from './debug.js';
|
|
2
2
|
import type { Translator } from '@markuplint/i18n';
|
|
3
|
+
import type { PlainData } from '@markuplint/ml-config';
|
|
3
4
|
import type { Element, RuleConfigValue, Document } from '@markuplint/ml-core';
|
|
4
5
|
import type { Attribute } from '@markuplint/ml-spec';
|
|
5
|
-
|
|
6
|
+
import type { WritableDeep } from 'type-fest';
|
|
7
|
+
export declare function attrMatches<T extends RuleConfigValue, O extends PlainData>(node: Element<T, O>, condition: Attribute['condition']): boolean;
|
|
6
8
|
export declare function match(needle: string, pattern: string): boolean;
|
|
7
9
|
/**
|
|
8
10
|
* PotentialCustomElementName
|
|
@@ -20,8 +22,8 @@ export declare function match(needle: string, pattern: string): boolean;
|
|
|
20
22
|
* Originally, it is not possible to define a name including ASCII upper alphas in the custom element, but it is not treated as illegal by the HTML parser.
|
|
21
23
|
*/
|
|
22
24
|
export declare const rePCENChar: string;
|
|
23
|
-
export declare function isValidAttr(t: Translator, name: string, value: string, isDynamicValue: boolean, node: Element<any, any>, attrSpecs: Attribute[], log?: Log): false | {
|
|
24
|
-
invalidType: "non-existent" | "invalid-value";
|
|
25
|
+
export declare function isValidAttr(t: Translator, name: string, value: string, isDynamicValue: boolean, node: Element<any, any>, attrSpecs: readonly Attribute[], log?: Log): false | {
|
|
26
|
+
invalidType: "non-existent" | "invalid-value" | "disallowed-attr";
|
|
25
27
|
message: string;
|
|
26
28
|
loc?: {
|
|
27
29
|
raw: string;
|
|
@@ -31,17 +33,12 @@ export declare function isValidAttr(t: Translator, name: string, value: string,
|
|
|
31
33
|
};
|
|
32
34
|
export declare function toNormalizedValue(value: string, spec: Attribute): string;
|
|
33
35
|
export declare function accnameMayBeMutable(el: Element<any, any>, document: Document<any, any>): boolean;
|
|
34
|
-
export declare function getOwnedLabel<V extends RuleConfigValue, O>(el: Element<V, O>, document: Document<V, O>): Element<V, O> | null;
|
|
35
|
-
export declare function decodeCharRef(characterReference: string): string;
|
|
36
|
+
export declare function getOwnedLabel<V extends RuleConfigValue, O extends PlainData>(el: Element<V, O>, document: Document<V, O>): Element<V, O> | null;
|
|
36
37
|
export declare class Collection<T> {
|
|
37
38
|
#private;
|
|
38
|
-
constructor(...items: (T | null | undefined)[]);
|
|
39
|
+
constructor(...items: readonly (T | null | undefined)[]);
|
|
39
40
|
[Symbol.iterator](): Iterator<T>;
|
|
40
|
-
add(...items: (T | null | undefined)[]): void;
|
|
41
|
+
add(...items: readonly (T | null | undefined)[]): void;
|
|
41
42
|
toArray(): readonly T[];
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
-
-readonly [P in keyof T]: T[P];
|
|
45
|
-
};
|
|
46
|
-
export declare function deepCopy<T>(value: T): Writeable<T>;
|
|
47
|
-
export {};
|
|
44
|
+
export declare function deepCopy<T>(value: T): WritableDeep<T>;
|
package/lib/helpers.js
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var _Collection_items;
|
|
3
|
-
|
|
4
|
-
exports.deepCopy = exports.Collection = exports.decodeCharRef = exports.getOwnedLabel = exports.accnameMayBeMutable = exports.toNormalizedValue = exports.isValidAttr = exports.rePCENChar = exports.match = exports.attrMatches = void 0;
|
|
5
|
-
const tslib_1 = require("tslib");
|
|
2
|
+
import { __classPrivateFieldGet } from "tslib";
|
|
6
3
|
// @ts-ignore
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
import structuredClone from '@ungap/structured-clone';
|
|
5
|
+
import { attrCheck } from './attr-check.js';
|
|
6
|
+
export function attrMatches(
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
8
|
+
node, condition) {
|
|
9
|
+
if (condition == null) {
|
|
12
10
|
return true;
|
|
13
11
|
}
|
|
14
|
-
const condSelector =
|
|
12
|
+
const condSelector = typeof condition === 'string' ? condition : condition.join(',');
|
|
15
13
|
return node.matches(condSelector);
|
|
16
14
|
}
|
|
17
|
-
|
|
18
|
-
function match(needle, pattern) {
|
|
15
|
+
export function match(needle, pattern) {
|
|
19
16
|
const matches = pattern.match(/^\/(.*)\/(i|g|m)*$/);
|
|
20
17
|
if (matches && matches[1]) {
|
|
21
18
|
const re = matches[1];
|
|
@@ -24,7 +21,6 @@ function match(needle, pattern) {
|
|
|
24
21
|
}
|
|
25
22
|
return needle === pattern;
|
|
26
23
|
}
|
|
27
|
-
exports.match = match;
|
|
28
24
|
/**
|
|
29
25
|
* PotentialCustomElementName
|
|
30
26
|
*
|
|
@@ -40,7 +36,7 @@ exports.match = match;
|
|
|
40
36
|
* ASCII-case-insensitively.
|
|
41
37
|
* Originally, it is not possible to define a name including ASCII upper alphas in the custom element, but it is not treated as illegal by the HTML parser.
|
|
42
38
|
*/
|
|
43
|
-
|
|
39
|
+
export const rePCENChar = [
|
|
44
40
|
'\\-',
|
|
45
41
|
'\\.',
|
|
46
42
|
'[0-9]',
|
|
@@ -60,24 +56,31 @@ exports.rePCENChar = [
|
|
|
60
56
|
'[\uFDF0-\uFFFD]',
|
|
61
57
|
'[\uD800-\uDBFF][\uDC00-\uDFFF]',
|
|
62
58
|
].join('|');
|
|
63
|
-
function isValidAttr(t, name, value, isDynamicValue,
|
|
59
|
+
export function isValidAttr(t, name, value, isDynamicValue,
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
61
|
+
node, attrSpecs,
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
63
|
+
log) {
|
|
64
64
|
let invalid = false;
|
|
65
65
|
const spec = attrSpecs.find(s => s.name.toLowerCase() === name.toLowerCase());
|
|
66
66
|
log && log('Spec of the %s attr: %o', name, spec);
|
|
67
|
-
invalid =
|
|
68
|
-
if (
|
|
67
|
+
invalid = attrCheck(t, name, value, false, spec);
|
|
68
|
+
if (invalid === false &&
|
|
69
|
+
spec &&
|
|
70
|
+
spec.condition != null &&
|
|
71
|
+
!node.hasSpreadAttr &&
|
|
72
|
+
!attrMatches(node, spec.condition)) {
|
|
69
73
|
invalid = {
|
|
70
74
|
invalidType: 'non-existent',
|
|
71
75
|
message: t('{0} is {1}', t('the "{0*}" {1}', name, 'attribute'), 'disallowed'),
|
|
72
76
|
};
|
|
73
77
|
}
|
|
74
|
-
if (invalid && invalid.invalidType === 'invalid-value' && isDynamicValue) {
|
|
78
|
+
if (invalid !== false && invalid.invalidType === 'invalid-value' && isDynamicValue) {
|
|
75
79
|
invalid = false;
|
|
76
80
|
}
|
|
77
81
|
return invalid;
|
|
78
82
|
}
|
|
79
|
-
|
|
80
|
-
function toNormalizedValue(value, spec) {
|
|
83
|
+
export function toNormalizedValue(value, spec) {
|
|
81
84
|
let normalized = value;
|
|
82
85
|
if (!spec.caseSensitive) {
|
|
83
86
|
normalized = normalized.toLowerCase();
|
|
@@ -105,8 +108,11 @@ function toNormalizedValue(value, spec) {
|
|
|
105
108
|
}
|
|
106
109
|
return normalized;
|
|
107
110
|
}
|
|
108
|
-
|
|
109
|
-
|
|
111
|
+
export function accnameMayBeMutable(
|
|
112
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
113
|
+
el,
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
115
|
+
document) {
|
|
110
116
|
if (el.hasMutableAttributes() || el.hasMutableChildren(true)) {
|
|
111
117
|
return true;
|
|
112
118
|
}
|
|
@@ -116,9 +122,12 @@ function accnameMayBeMutable(el, document) {
|
|
|
116
122
|
}
|
|
117
123
|
return false;
|
|
118
124
|
}
|
|
119
|
-
exports.accnameMayBeMutable = accnameMayBeMutable;
|
|
120
125
|
const labelable = ['button', 'input:not([type=hidden])', 'meter', 'output', 'progress', 'select', 'textarea'];
|
|
121
|
-
function getOwnedLabel(
|
|
126
|
+
export function getOwnedLabel(
|
|
127
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
128
|
+
el,
|
|
129
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
130
|
+
document) {
|
|
122
131
|
if (!labelable.some(cond => el.matches(cond))) {
|
|
123
132
|
return null;
|
|
124
133
|
}
|
|
@@ -131,33 +140,26 @@ function getOwnedLabel(el, document) {
|
|
|
131
140
|
}
|
|
132
141
|
return ownedLabel;
|
|
133
142
|
}
|
|
134
|
-
|
|
135
|
-
function decodeCharRef(characterReference) {
|
|
136
|
-
return (0, html_entities_1.decode)(characterReference);
|
|
137
|
-
}
|
|
138
|
-
exports.decodeCharRef = decodeCharRef;
|
|
139
|
-
class Collection {
|
|
143
|
+
export class Collection {
|
|
140
144
|
constructor(...items) {
|
|
141
145
|
_Collection_items.set(this, new Set());
|
|
142
146
|
this.add(...items);
|
|
143
147
|
}
|
|
144
148
|
[(_Collection_items = new WeakMap(), Symbol.iterator)]() {
|
|
145
|
-
return
|
|
149
|
+
return __classPrivateFieldGet(this, _Collection_items, "f").values();
|
|
146
150
|
}
|
|
147
151
|
add(...items) {
|
|
148
152
|
for (const item of items) {
|
|
149
153
|
if (item == null) {
|
|
150
154
|
continue;
|
|
151
155
|
}
|
|
152
|
-
|
|
156
|
+
__classPrivateFieldGet(this, _Collection_items, "f").add(item);
|
|
153
157
|
}
|
|
154
158
|
}
|
|
155
159
|
toArray() {
|
|
156
|
-
return Object.freeze(Array.from(
|
|
160
|
+
return Object.freeze(Array.from(__classPrivateFieldGet(this, _Collection_items, "f")));
|
|
157
161
|
}
|
|
158
162
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
return (0, structured_clone_1.default)(value);
|
|
163
|
+
export function deepCopy(value) {
|
|
164
|
+
return structuredClone(value);
|
|
162
165
|
}
|
|
163
|
-
exports.deepCopy = deepCopy;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue,
|
|
1
|
+
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
2
2
|
export default _default;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const ml_core_1 = require("@markuplint/ml-core");
|
|
4
|
-
exports.default = (0, ml_core_1.createRule)({
|
|
1
|
+
import { createRule } from '@markuplint/ml-core';
|
|
2
|
+
export default createRule({
|
|
5
3
|
async verify({ document, report, t }) {
|
|
6
4
|
const message = t('{0} is {1:c}', t('{0} of {1}', t('the {0}', 'value'), t('the "{0*}" {1}', 'id', 'attribute')), 'duplicated');
|
|
7
5
|
const idStack = [];
|
package/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,102 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
declare const rules: {
|
|
2
|
+
readonly 'attr-duplication': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
3
|
+
readonly 'attr-value-quotes': Readonly<import("@markuplint/ml-core").RuleSeed<import("./attr-value-quotes/index.js").Type, undefined>>;
|
|
4
|
+
readonly 'case-sensitive-attr-name': Readonly<import("@markuplint/ml-core").RuleSeed<import("./case-sensitive-attr-name/index.js").Value, undefined>>;
|
|
5
|
+
readonly 'case-sensitive-tag-name': Readonly<import("@markuplint/ml-core").RuleSeed<import("./case-sensitive-tag-name/index.js").Value, undefined>>;
|
|
6
|
+
readonly 'character-reference': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
7
|
+
readonly 'class-naming': Readonly<import("@markuplint/ml-core").RuleSeed<import("./class-naming/index.js").Value, undefined>>;
|
|
8
|
+
readonly 'deprecated-attr': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
9
|
+
readonly 'deprecated-element': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
10
|
+
readonly 'disallowed-element': Readonly<import("@markuplint/ml-core").RuleSeed<string[], undefined>>;
|
|
11
|
+
readonly doctype: Readonly<import("@markuplint/ml-core").RuleSeed<"always", {
|
|
12
|
+
denyObsoleteType: boolean;
|
|
13
|
+
}>>;
|
|
14
|
+
readonly 'end-tag': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, undefined>>;
|
|
15
|
+
readonly 'id-duplication': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
16
|
+
readonly 'ineffective-attr': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
17
|
+
readonly 'invalid-attr': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, {
|
|
18
|
+
allowAttrs?: (string | {
|
|
19
|
+
name: string;
|
|
20
|
+
value: ({
|
|
21
|
+
enum: [string, ...string[]];
|
|
22
|
+
} | {
|
|
23
|
+
pattern: string;
|
|
24
|
+
} | {
|
|
25
|
+
type: import("packages/@markuplint/ml-spec/lib/index.js").AttributeType;
|
|
26
|
+
}) | import("packages/@markuplint/ml-spec/lib/index.js").AttributeType;
|
|
27
|
+
})[] | Record<string, {
|
|
28
|
+
enum: [string, ...string[]];
|
|
29
|
+
} | {
|
|
30
|
+
pattern: string;
|
|
31
|
+
} | {
|
|
32
|
+
type: import("packages/@markuplint/ml-spec/lib/index.js").AttributeType;
|
|
33
|
+
}> | undefined;
|
|
34
|
+
disallowAttrs?: (string | {
|
|
35
|
+
name: string;
|
|
36
|
+
value: ({
|
|
37
|
+
enum: [string, ...string[]];
|
|
38
|
+
} | {
|
|
39
|
+
pattern: string;
|
|
40
|
+
} | {
|
|
41
|
+
type: import("packages/@markuplint/ml-spec/lib/index.js").AttributeType;
|
|
42
|
+
}) | import("packages/@markuplint/ml-spec/lib/index.js").AttributeType;
|
|
43
|
+
})[] | Record<string, {
|
|
44
|
+
enum: [string, ...string[]];
|
|
45
|
+
} | {
|
|
46
|
+
pattern: string;
|
|
47
|
+
} | {
|
|
48
|
+
type: import("packages/@markuplint/ml-spec/lib/index.js").AttributeType;
|
|
49
|
+
}> | undefined;
|
|
50
|
+
ignoreAttrNamePrefix?: string | string[] | undefined;
|
|
51
|
+
allowToAddPropertiesForPretender?: boolean | undefined;
|
|
52
|
+
attrs?: Record<string, ({
|
|
53
|
+
enum: [string, ...string[]];
|
|
54
|
+
} | {
|
|
55
|
+
pattern: string;
|
|
56
|
+
} | {
|
|
57
|
+
type: import("packages/@markuplint/ml-spec/lib/index.js").AttributeType;
|
|
58
|
+
}) | {
|
|
59
|
+
disallowed: true;
|
|
60
|
+
}> | undefined;
|
|
61
|
+
}>>;
|
|
62
|
+
readonly 'label-has-control': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
63
|
+
readonly 'landmark-roles': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, {
|
|
64
|
+
ignoreRoles: (("banner" | "main" | "complementary" | "contentinfo") | "form" | "navigation" | "region")[];
|
|
65
|
+
labelEachArea: boolean;
|
|
66
|
+
}>>;
|
|
67
|
+
readonly 'no-boolean-attr-value': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
68
|
+
readonly 'no-default-value': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
69
|
+
readonly 'no-empty-palpable-content': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, {
|
|
70
|
+
extendsExposableElements?: boolean | undefined;
|
|
71
|
+
ignoreIfAriaBusy?: boolean | undefined;
|
|
72
|
+
}>>;
|
|
73
|
+
readonly 'no-hard-code-id': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
74
|
+
readonly 'no-refer-to-non-existent-id': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, {
|
|
75
|
+
ariaVersion: "1.1" | "1.2" | "1.3";
|
|
76
|
+
fragmentRefersNameAttr: boolean;
|
|
77
|
+
}>>;
|
|
78
|
+
readonly 'no-use-event-handler-attr': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, {
|
|
79
|
+
ignore?: string | string[] | undefined;
|
|
80
|
+
}>>;
|
|
81
|
+
readonly 'permitted-contents': Readonly<import("@markuplint/ml-core").RuleSeed<import("./permitted-contents/types.js").TagRule[], import("./permitted-contents/types.js").Options>>;
|
|
82
|
+
readonly 'placeholder-label-option': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, undefined>>;
|
|
83
|
+
readonly 'require-accessible-name': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, {
|
|
84
|
+
ariaVersion: "1.1" | "1.2" | "1.3";
|
|
85
|
+
}>>;
|
|
86
|
+
readonly 'require-datetime': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, {
|
|
87
|
+
langs?: import("./require-datetime/types.js").Lang[] | undefined;
|
|
88
|
+
}>>;
|
|
89
|
+
readonly 'required-attr': Readonly<import("@markuplint/ml-core").RuleSeed<string | (string | {
|
|
90
|
+
name: string;
|
|
91
|
+
value?: string | string[] | undefined;
|
|
92
|
+
})[], undefined>>;
|
|
93
|
+
readonly 'required-element': Readonly<import("@markuplint/ml-core").RuleSeed<string[], {
|
|
94
|
+
ignoreHasMutableContents: boolean;
|
|
95
|
+
}>>;
|
|
96
|
+
readonly 'required-h1': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, import("./required-h1/index.js").Options>>;
|
|
97
|
+
readonly 'use-list': Readonly<import("@markuplint/ml-core").RuleSeed<readonly string[], {
|
|
98
|
+
spaceNeededBullets?: string[] | undefined;
|
|
99
|
+
}>>;
|
|
100
|
+
readonly 'wai-aria': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, import("./wai-aria/types.js").Options>>;
|
|
101
|
+
};
|
|
102
|
+
export default rules;
|
package/lib/index.js
CHANGED
|
@@ -1,63 +1,65 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
'attr-
|
|
35
|
-
'attr-
|
|
36
|
-
'case-sensitive-
|
|
37
|
-
'
|
|
38
|
-
'
|
|
39
|
-
'
|
|
40
|
-
'deprecated-
|
|
41
|
-
'
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
'
|
|
45
|
-
'
|
|
46
|
-
'
|
|
47
|
-
'
|
|
48
|
-
'
|
|
49
|
-
'
|
|
50
|
-
'no-
|
|
51
|
-
'no-
|
|
52
|
-
'no-
|
|
53
|
-
'no-
|
|
54
|
-
'no-
|
|
55
|
-
'
|
|
56
|
-
'
|
|
57
|
-
'require-accessible-name':
|
|
58
|
-
'
|
|
59
|
-
'required-
|
|
60
|
-
'required-
|
|
61
|
-
'
|
|
62
|
-
'
|
|
1
|
+
import AttrDuplication from './attr-duplication/index.js';
|
|
2
|
+
import AttrValueQuotes from './attr-value-quotes/index.js';
|
|
3
|
+
import CaseSensitiveAttrName from './case-sensitive-attr-name/index.js';
|
|
4
|
+
import CaseSensitiveTagName from './case-sensitive-tag-name/index.js';
|
|
5
|
+
import CharacterReference from './character-reference/index.js';
|
|
6
|
+
import ClassNaming from './class-naming/index.js';
|
|
7
|
+
import DeprecatedAttr from './deprecated-attr/index.js';
|
|
8
|
+
import DeprecatedElement from './deprecated-element/index.js';
|
|
9
|
+
import DisallowedElement from './disallowed-element/index.js';
|
|
10
|
+
import Doctype from './doctype/index.js';
|
|
11
|
+
import EndTag from './end-tag/index.js';
|
|
12
|
+
import IdDuplication from './id-duplication/index.js';
|
|
13
|
+
import IneffectiveAttr from './ineffective-attr/index.js';
|
|
14
|
+
import InvalidAttr from './invalid-attr/index.js';
|
|
15
|
+
import LabelHasControl from './label-has-control/index.js';
|
|
16
|
+
import LandmarkRoles from './landmark-roles/index.js';
|
|
17
|
+
import NoBooleanAttrValue from './no-boolean-attr-value/index.js';
|
|
18
|
+
import NoDefaultValue from './no-default-value/index.js';
|
|
19
|
+
import NoEmptyPalpableContent from './no-empty-palpable-content/index.js';
|
|
20
|
+
import NoHardCodeId from './no-hard-code-id/index.js';
|
|
21
|
+
import NoReferToNonExistentId from './no-refer-to-non-existent-id/index.js';
|
|
22
|
+
import NoUseEventHandlerAttr from './no-use-event-handler-attr/index.js';
|
|
23
|
+
import PermittedContents from './permitted-contents/index.js';
|
|
24
|
+
import PlaceholderLabelOption from './placeholder-label-option/index.js';
|
|
25
|
+
import RequireAccessibleName from './require-accessible-name/index.js';
|
|
26
|
+
import RequireDatetime from './require-datetime/index.js';
|
|
27
|
+
import RequiredAttr from './required-attr/index.js';
|
|
28
|
+
import RequiredElement from './required-element/index.js';
|
|
29
|
+
import RequiredH1 from './required-h1/index.js';
|
|
30
|
+
import UseList from './use-list/index.js';
|
|
31
|
+
import WaiAria from './wai-aria/index.js';
|
|
32
|
+
const rules = {
|
|
33
|
+
'attr-duplication': AttrDuplication,
|
|
34
|
+
'attr-value-quotes': AttrValueQuotes,
|
|
35
|
+
'case-sensitive-attr-name': CaseSensitiveAttrName,
|
|
36
|
+
'case-sensitive-tag-name': CaseSensitiveTagName,
|
|
37
|
+
'character-reference': CharacterReference,
|
|
38
|
+
'class-naming': ClassNaming,
|
|
39
|
+
'deprecated-attr': DeprecatedAttr,
|
|
40
|
+
'deprecated-element': DeprecatedElement,
|
|
41
|
+
'disallowed-element': DisallowedElement,
|
|
42
|
+
doctype: Doctype,
|
|
43
|
+
'end-tag': EndTag,
|
|
44
|
+
'id-duplication': IdDuplication,
|
|
45
|
+
'ineffective-attr': IneffectiveAttr,
|
|
46
|
+
'invalid-attr': InvalidAttr,
|
|
47
|
+
'label-has-control': LabelHasControl,
|
|
48
|
+
'landmark-roles': LandmarkRoles,
|
|
49
|
+
'no-boolean-attr-value': NoBooleanAttrValue,
|
|
50
|
+
'no-default-value': NoDefaultValue,
|
|
51
|
+
'no-empty-palpable-content': NoEmptyPalpableContent,
|
|
52
|
+
'no-hard-code-id': NoHardCodeId,
|
|
53
|
+
'no-refer-to-non-existent-id': NoReferToNonExistentId,
|
|
54
|
+
'no-use-event-handler-attr': NoUseEventHandlerAttr,
|
|
55
|
+
'permitted-contents': PermittedContents,
|
|
56
|
+
'placeholder-label-option': PlaceholderLabelOption,
|
|
57
|
+
'require-accessible-name': RequireAccessibleName,
|
|
58
|
+
'require-datetime': RequireDatetime,
|
|
59
|
+
'required-attr': RequiredAttr,
|
|
60
|
+
'required-element': RequiredElement,
|
|
61
|
+
'required-h1': RequiredH1,
|
|
62
|
+
'use-list': UseList,
|
|
63
|
+
'wai-aria': WaiAria,
|
|
63
64
|
};
|
|
65
|
+
export default rules;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue,
|
|
1
|
+
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
2
2
|
export default _default;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
exports.default = (0, ml_core_1.createRule)({
|
|
1
|
+
import { createRule, getAttrSpecs } from '@markuplint/ml-core';
|
|
2
|
+
import { toNoEmptyStringArrayFromStringOrArray } from '@markuplint/shared';
|
|
3
|
+
export default createRule({
|
|
5
4
|
defaultSeverity: 'warning',
|
|
6
5
|
async verify({ document, report, t }) {
|
|
7
6
|
await document.walkOn('Attr', attr => {
|
|
8
|
-
const attrSpec =
|
|
7
|
+
const attrSpec = getAttrSpecs(attr.ownerElement, document.specs);
|
|
9
8
|
if (!attrSpec) {
|
|
10
9
|
return;
|
|
11
10
|
}
|
|
@@ -14,11 +13,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
14
13
|
if (!spec) {
|
|
15
14
|
return;
|
|
16
15
|
}
|
|
17
|
-
const ineffectiveConditions = spec.ineffective
|
|
18
|
-
? Array.isArray(spec.ineffective)
|
|
19
|
-
? spec.ineffective
|
|
20
|
-
: [spec.ineffective]
|
|
21
|
-
: [];
|
|
16
|
+
const ineffectiveConditions = toNoEmptyStringArrayFromStringOrArray(spec.ineffective);
|
|
22
17
|
if (ineffectiveConditions.some(selector => attr.ownerElement.matches(selector))) {
|
|
23
18
|
report({
|
|
24
19
|
scope: attr,
|
|
@@ -1,17 +1,37 @@
|
|
|
1
1
|
import type { AttributeType } from '@markuplint/ml-spec';
|
|
2
2
|
type Option = {
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* @since 3.7.0
|
|
5
|
+
*/
|
|
6
|
+
allowAttrs?: (string | Attr)[] | Record<string, ValueRule>;
|
|
7
|
+
/**
|
|
8
|
+
* @since 3.7.0
|
|
9
|
+
*/
|
|
10
|
+
disallowAttrs?: (string | Attr)[] | Record<string, ValueRule>;
|
|
4
11
|
ignoreAttrNamePrefix?: string | string[];
|
|
5
12
|
allowToAddPropertiesForPretender?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* @deprecated Since version 3.7.0. Use `allowAttrs` or `disallowAttrs` instead.
|
|
15
|
+
* This option (`attr`) is now considered ambiguous and may lead to confusion.
|
|
16
|
+
* Please use the more explicit `allowAttrs` or `disallowAttrs` option
|
|
17
|
+
* to specify allowed attributes for the `invalid-attr` rule.
|
|
18
|
+
* @see {@link Option.allowAttrs}
|
|
19
|
+
* @see {@link Option.disallowAttrs}
|
|
20
|
+
*/
|
|
21
|
+
attrs?: Record<string, ValueRule | {
|
|
22
|
+
disallowed: true;
|
|
23
|
+
}>;
|
|
6
24
|
};
|
|
7
|
-
type
|
|
25
|
+
type Attr = {
|
|
26
|
+
name: string;
|
|
27
|
+
value: AttributeType | ValueRule;
|
|
28
|
+
};
|
|
29
|
+
type ValueRule = {
|
|
8
30
|
enum: [string, ...string[]];
|
|
9
31
|
} | {
|
|
10
32
|
pattern: string;
|
|
11
33
|
} | {
|
|
12
34
|
type: AttributeType;
|
|
13
|
-
} | {
|
|
14
|
-
disallowed: true;
|
|
15
35
|
};
|
|
16
|
-
declare const _default: import("@markuplint/ml-core").RuleSeed<boolean, Option
|
|
36
|
+
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, Option>>;
|
|
17
37
|
export default _default;
|