@markuplint/rules 1.10.2 → 2.0.0-alpha.0.23

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.
Files changed (57) hide show
  1. package/README.md +21 -20
  2. package/lib/attr-check.d.ts +16 -0
  3. package/lib/attr-check.js +498 -0
  4. package/lib/attr-duplication/index.d.ts +1 -1
  5. package/lib/attr-duplication/index.js +5 -8
  6. package/lib/attr-equal-space-after/index.d.ts +1 -1
  7. package/lib/attr-equal-space-after/index.js +8 -11
  8. package/lib/attr-equal-space-before/index.d.ts +1 -1
  9. package/lib/attr-equal-space-before/index.js +8 -11
  10. package/lib/attr-spacing/index.d.ts +3 -3
  11. package/lib/attr-spacing/index.js +19 -21
  12. package/lib/attr-value-quotes/index.d.ts +1 -1
  13. package/lib/attr-value-quotes/index.js +9 -12
  14. package/lib/case-sensitive-attr-name/index.d.ts +1 -1
  15. package/lib/case-sensitive-attr-name/index.js +11 -14
  16. package/lib/case-sensitive-tag-name/index.d.ts +1 -1
  17. package/lib/case-sensitive-tag-name/index.js +8 -11
  18. package/lib/character-reference/index.d.ts +1 -1
  19. package/lib/character-reference/index.js +15 -11
  20. package/lib/class-naming/index.d.ts +1 -1
  21. package/lib/class-naming/index.js +7 -10
  22. package/lib/deprecated-attr/index.d.ts +1 -1
  23. package/lib/deprecated-attr/index.js +6 -9
  24. package/lib/deprecated-element/index.d.ts +1 -1
  25. package/lib/deprecated-element/index.js +10 -15
  26. package/lib/doctype/index.d.ts +1 -1
  27. package/lib/doctype/index.js +16 -25
  28. package/lib/helpers.d.ts +12 -11
  29. package/lib/helpers.js +38 -25
  30. package/lib/id-duplication/index.d.ts +1 -1
  31. package/lib/id-duplication/index.js +5 -8
  32. package/lib/indentation/index.d.ts +3 -3
  33. package/lib/indentation/index.js +81 -116
  34. package/lib/index.d.ts +45 -24
  35. package/lib/index.js +42 -42
  36. package/lib/invalid-attr/index.d.ts +2 -2
  37. package/lib/invalid-attr/index.js +23 -25
  38. package/lib/landmark-roles/index.d.ts +3 -3
  39. package/lib/landmark-roles/index.js +12 -20
  40. package/lib/permitted-contents/index.d.ts +2 -2
  41. package/lib/permitted-contents/index.js +63 -45
  42. package/lib/permitted-contents/permitted-content.spec-to-regexp.d.ts +2 -2
  43. package/lib/permitted-contents/permitted-content.spec-to-regexp.js +49 -30
  44. package/lib/permitted-contents/unfold-content-models-to-tags.d.ts +1 -1
  45. package/lib/permitted-contents/unfold-content-models-to-tags.js +2 -3
  46. package/lib/{type-check.d.ts → primitive-check.d.ts} +24 -7
  47. package/lib/primitive-check.js +109 -0
  48. package/lib/required-attr/index.d.ts +1 -1
  49. package/lib/required-attr/index.js +12 -16
  50. package/lib/required-h1/index.d.ts +3 -3
  51. package/lib/required-h1/index.js +8 -13
  52. package/lib/wai-aria/index.d.ts +1 -1
  53. package/lib/wai-aria/index.js +57 -64
  54. package/package.json +6 -6
  55. package/tsconfig.test.json +1 -24
  56. package/tsconfig.tsbuildinfo +1 -1
  57. package/lib/type-check.js +0 -321
package/lib/helpers.d.ts CHANGED
@@ -1,12 +1,13 @@
1
- import { ARIRRoleAttribute, Attribute, MLMLSpec, PermittedRoles } from '@markuplint/ml-spec';
2
- import { Element, RuleConfigValue } from '@markuplint/ml-core';
3
- export declare function getAttrSpecs(tag: string, { specs, def }: MLMLSpec): Attribute[] | null;
1
+ import type { Translator } from '@markuplint/i18n';
2
+ import type { Element, RuleConfigValue } from '@markuplint/ml-core';
3
+ import type { ARIRRoleAttribute, Attribute, MLMLSpec, PermittedRoles } from '@markuplint/ml-spec';
4
+ export declare function getAttrSpecs(nameWithNS: string, { specs, def }: MLMLSpec): Attribute[] | null;
4
5
  export declare function attrMatches<T extends RuleConfigValue, R>(node: Element<T, R>, condition: Attribute['condition']): boolean;
5
6
  export declare function match(needle: string, pattern: string): boolean;
6
7
  /**
7
8
  * PotentialCustomElementName
8
9
  *
9
- * @see https://html.spec.whatwg.org/multipage/custom-elements.html#prod-potentialcustomelementname
10
+ * @see https://spec.whatwg.org/multipage/custom-elements.html#prod-potentialcustomelementname
10
11
  *
11
12
  * > PotentialCustomElementName ::=
12
13
  * > [a-z] (PCENChar)* '-' (PCENChar)*
@@ -19,19 +20,19 @@ export declare function match(needle: string, pattern: string): boolean;
19
20
  * 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.
20
21
  */
21
22
  export declare const rePCENChar: string;
22
- export declare function htmlSpec(tag: string): import("packages/@markuplint/ml-spec/src").ElementSpec | null;
23
- export declare function isValidAttr(name: string, value: string, isDynamicValue: boolean, node: Element<any, any>, attrSpecs: Attribute[]): false | {
23
+ export declare function htmlSpec(nameWithNS: string): import("@markuplint/ml-spec").ElementSpec | null;
24
+ export declare function isValidAttr(t: Translator, name: string, value: string, isDynamicValue: boolean, node: Element<any, any>, attrSpecs: Attribute[]): false | {
24
25
  invalidType: "non-existent" | "invalid-value";
25
26
  message: string;
26
27
  };
27
28
  export declare function ariaSpec(): {
28
29
  roles: ARIRRoleAttribute[];
29
- ariaAttrs: import("packages/@markuplint/ml-spec/src").ARIAAttribute[];
30
+ ariaAttrs: import("@markuplint/ml-spec").ARIAAttribute[];
30
31
  };
31
32
  export declare function getRoleSpec(roleName: string): {
32
33
  name: string;
33
34
  isAbstract: boolean;
34
- statesAndProps: import("packages/@markuplint/ml-spec/src").ARIARoleOwnedPropOrState[];
35
+ statesAndProps: import("@markuplint/ml-spec").ARIARoleOwnedPropOrState[];
35
36
  superClassRoles: ARIRRoleAttribute[];
36
37
  } | null;
37
38
  /**
@@ -66,13 +67,13 @@ export declare function checkAria(attrName: string, currentValue: string, role?:
66
67
  type: "property" | "state";
67
68
  deprecated?: true | undefined;
68
69
  isGlobal?: true | undefined;
69
- value: import("packages/@markuplint/ml-spec/src").ARIAAttributeValue;
70
+ value: import("@markuplint/ml-spec").ARIAAttributeValue;
70
71
  conditionalValue?: {
71
72
  role: string[];
72
- value: import("packages/@markuplint/ml-spec/src").ARIAAttributeValue;
73
+ value: import("@markuplint/ml-spec").ARIAAttributeValue;
73
74
  }[] | undefined;
74
75
  enum: string[];
75
76
  defaultValue?: string | undefined;
76
- equivalentHtmlAttrs?: import("packages/@markuplint/ml-spec/src").EquivalentHtmlAttr[] | undefined;
77
+ equivalentHtmlAttrs?: import("@markuplint/ml-spec").EquivalentHtmlAttr[] | undefined;
77
78
  valueDescriptions?: Record<string, string> | undefined;
78
79
  };
package/lib/helpers.js CHANGED
@@ -1,31 +1,42 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.checkAria = exports.checkAriaValue = exports.getComputedRole = exports.getImplicitRole = exports.getPermittedRoles = exports.getRoleSpec = exports.ariaSpec = exports.isValidAttr = exports.htmlSpec = exports.rePCENChar = exports.match = exports.attrMatches = exports.getAttrSpecs = void 0;
4
- const tslib_1 = require("tslib");
5
- const html_spec_1 = tslib_1.__importDefault(require("@markuplint/html-spec"));
6
- const type_check_1 = require("./type-check");
7
- function getAttrSpecs(tag, { specs, def }) {
8
- tag = tag.toLowerCase();
9
- const spec = specs.find(spec => spec.name === tag);
4
+ const html_spec_1 = require("@markuplint/html-spec");
5
+ const attr_check_1 = require("./attr-check");
6
+ function getAttrSpecs(nameWithNS, { specs, def }) {
7
+ const spec = specs.find(spec => spec.name === nameWithNS);
10
8
  if (!spec) {
11
9
  return null;
12
10
  }
13
- const hasGlobalAttr = spec.attributes.some(attr => attr === '#globalAttrs');
11
+ const globalAttrs = def['#globalAttrs'];
14
12
  const attrs = [];
15
- if (hasGlobalAttr) {
16
- attrs.push(...def['#globalAttrs']);
13
+ if (!/[a-z]:[a-z]/i.test(nameWithNS)) {
14
+ // It's HTML tag
15
+ const hasGlobalAttr = spec.attributes.some(attr => attr === '#globalAttrs');
16
+ if (hasGlobalAttr) {
17
+ attrs.push(...(globalAttrs['#HTMLGlobalAttrs'] || []));
18
+ }
17
19
  }
18
20
  for (const attr of spec.attributes) {
19
21
  if (typeof attr === 'string') {
22
+ const globalAttr = globalAttrs[attr];
23
+ if (!globalAttr) {
24
+ continue;
25
+ }
26
+ attrs.push(...globalAttr);
20
27
  continue;
21
28
  }
22
29
  const definedIndex = attrs.findIndex(a => a.name === attr.name);
23
30
  if (definedIndex !== -1) {
24
- attrs[definedIndex] = Object.assign(Object.assign({}, attrs[definedIndex]), attr);
31
+ attrs[definedIndex] = {
32
+ ...attrs[definedIndex],
33
+ ...attr,
34
+ };
25
35
  continue;
26
36
  }
27
37
  attrs.push(attr);
28
38
  }
39
+ attrs.push(...(globalAttrs['#extends'] || []));
29
40
  return attrs;
30
41
  }
31
42
  exports.getAttrSpecs = getAttrSpecs;
@@ -34,11 +45,11 @@ function attrMatches(node, condition) {
34
45
  return true;
35
46
  }
36
47
  let matched = false;
37
- if (condition.self) {
48
+ if ('self' in condition && condition.self) {
38
49
  const condSelector = Array.isArray(condition.self) ? condition.self.join(',') : condition.self;
39
50
  matched = node.matches(condSelector);
40
51
  }
41
- if (condition.ancestor) {
52
+ if ('ancestor' in condition && condition.ancestor) {
42
53
  let _node = node.parentNode;
43
54
  while (_node) {
44
55
  if (_node.type === 'Element') {
@@ -66,7 +77,7 @@ exports.match = match;
66
77
  /**
67
78
  * PotentialCustomElementName
68
79
  *
69
- * @see https://html.spec.whatwg.org/multipage/custom-elements.html#prod-potentialcustomelementname
80
+ * @see https://spec.whatwg.org/multipage/custom-elements.html#prod-potentialcustomelementname
70
81
  *
71
82
  * > PotentialCustomElementName ::=
72
83
  * > [a-z] (PCENChar)* '-' (PCENChar)*
@@ -98,20 +109,19 @@ exports.rePCENChar = [
98
109
  '[\uFDF0-\uFFFD]',
99
110
  '[\uD800-\uDBFF][\uDC00-\uDFFF]',
100
111
  ].join('|');
101
- function htmlSpec(tag) {
102
- tag = tag.toLowerCase();
103
- const spec = html_spec_1.default.specs.find(spec => spec.name === tag);
112
+ function htmlSpec(nameWithNS) {
113
+ const spec = html_spec_1.specs.find(spec => spec.name === nameWithNS);
104
114
  return spec || null;
105
115
  }
106
116
  exports.htmlSpec = htmlSpec;
107
- function isValidAttr(name, value, isDynamicValue, node, attrSpecs) {
117
+ function isValidAttr(t, name, value, isDynamicValue, node, attrSpecs) {
108
118
  let invalid = false;
109
119
  const spec = attrSpecs.find(s => s.name === name);
110
- invalid = type_check_1.typeCheck(name, value, false, spec);
120
+ invalid = (0, attr_check_1.attrCheck)(t, name, value, false, spec);
111
121
  if (!invalid && spec && spec.condition && !node.hasSpreadAttr && !attrMatches(node, spec.condition)) {
112
122
  invalid = {
113
123
  invalidType: 'non-existent',
114
- message: `The "${name}" attribute is not allowed`,
124
+ message: t('{0} is {1}', t('the "{0}" {1}', name, 'attribute'), 'disallowed'),
115
125
  };
116
126
  }
117
127
  if (invalid && invalid.invalidType === 'invalid-value' && isDynamicValue) {
@@ -121,8 +131,8 @@ function isValidAttr(name, value, isDynamicValue, node, attrSpecs) {
121
131
  }
122
132
  exports.isValidAttr = isValidAttr;
123
133
  function ariaSpec() {
124
- const roles = html_spec_1.default.def['#roles'];
125
- const ariaAttrs = html_spec_1.default.def['#ariaAttrs'];
134
+ const roles = html_spec_1.def['#roles'];
135
+ const ariaAttrs = html_spec_1.def['#ariaAttrs'];
126
136
  return {
127
137
  roles,
128
138
  ariaAttrs,
@@ -144,7 +154,7 @@ function getRoleSpec(roleName) {
144
154
  }
145
155
  exports.getRoleSpec = getRoleSpec;
146
156
  function getRoleByName(roleName) {
147
- const roles = html_spec_1.default.def['#roles'];
157
+ const roles = html_spec_1.def['#roles'];
148
158
  const role = roles.find(r => r.name === roleName);
149
159
  return role;
150
160
  }
@@ -282,7 +292,7 @@ function checkAriaValue(type, value, tokenEnum) {
282
292
  }
283
293
  exports.checkAriaValue = checkAriaValue;
284
294
  function checkAria(attrName, currentValue, role) {
285
- const ariaAttrs = html_spec_1.default.def['#ariaAttrs'];
295
+ const ariaAttrs = html_spec_1.def['#ariaAttrs'];
286
296
  const aria = ariaAttrs.find(a => a.name === attrName);
287
297
  if (!aria) {
288
298
  return {
@@ -301,7 +311,10 @@ function checkAria(attrName, currentValue, role) {
301
311
  }
302
312
  }
303
313
  const isValid = checkAriaValue(valueType, currentValue, aria.enum);
304
- return Object.assign(Object.assign({}, aria), { currentValue,
305
- isValid });
314
+ return {
315
+ ...aria,
316
+ currentValue,
317
+ isValid,
318
+ };
306
319
  }
307
320
  exports.checkAria = checkAria;
@@ -1,2 +1,2 @@
1
- declare const _default: import("@markuplint/ml-core").MLRule<null, null>;
1
+ declare const _default: import("@markuplint/ml-core").RuleSeed<null, null>;
2
2
  export default _default;
@@ -1,13 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ml_core_1 = require("@markuplint/ml-core");
4
- exports.default = ml_core_1.createRule({
5
- name: 'id-duplication',
4
+ exports.default = (0, ml_core_1.createRule)({
6
5
  defaultValue: null,
7
6
  defaultOptions: null,
8
- async verify(document, translate) {
9
- const reports = [];
10
- const message = translate('Duplicate {0}', 'attribute id value');
7
+ async verify({ document, report, t }) {
8
+ const message = t('{0} is {1:c}', t('{0} of {1}', t('the {0}', 'value'), t('the "{0}" {1}', 'id', 'attribute')), 'duplicated');
11
9
  const idStack = [];
12
10
  await document.walkOn('Element', async (node) => {
13
11
  const idAttrs = node.getAttributeToken('id');
@@ -19,8 +17,8 @@ exports.default = ml_core_1.createRule({
19
17
  }
20
18
  const id = idAttr.getValue();
21
19
  if (idStack.includes(id.raw)) {
22
- reports.push({
23
- severity: node.rule.severity,
20
+ report({
21
+ scope: node,
24
22
  message,
25
23
  line: idAttr.startLine,
26
24
  col: idAttr.startCol,
@@ -30,6 +28,5 @@ exports.default = ml_core_1.createRule({
30
28
  idStack.push(id.raw);
31
29
  }
32
30
  });
33
- return reports;
34
31
  },
35
32
  });
@@ -1,7 +1,7 @@
1
1
  export declare type Value = 'tab' | number;
2
2
  export interface IndentationOptions {
3
- alignment: boolean;
4
- 'indent-nested-nodes': boolean | 'always' | 'never';
3
+ alignment?: boolean;
4
+ 'indent-nested-nodes'?: boolean | 'always' | 'never';
5
5
  }
6
- declare const _default: import("@markuplint/ml-core").MLRule<Value, IndentationOptions>;
6
+ declare const _default: import("@markuplint/ml-core").RuleSeed<Value, IndentationOptions>;
7
7
  export default _default;
@@ -1,47 +1,45 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ml_core_1 = require("@markuplint/ml-core");
4
- exports.default = ml_core_1.createRule({
5
- name: 'indentation',
6
- defaultLevel: 'warning',
4
+ exports.default = (0, ml_core_1.createRule)({
5
+ defaultServerity: 'warning',
7
6
  defaultValue: 2,
8
7
  defaultOptions: {
9
8
  alignment: true,
10
9
  'indent-nested-nodes': true,
11
10
  },
12
- async verify(document, translate) {
13
- const reports = [];
14
- await document.walk(async (node) => {
11
+ async verify(context) {
12
+ await context.document.walk(async (node) => {
15
13
  if (node.rule.disabled) {
16
14
  return;
17
15
  }
18
- // console.log(`${node.type}(${'nodeName' in node ? node.nodeName : ''}):\t"${node.raw}"`);
19
- if (node.indentation) {
16
+ const indent = (0, ml_core_1.getIndent)(node);
17
+ if (indent) {
20
18
  /**
21
19
  * Validate indent type and length.
22
20
  */
23
- if (node.indentation.type !== 'none') {
21
+ if (indent.type !== 'none') {
24
22
  const ms = node.rule.severity === 'error' ? 'must' : 'should';
25
23
  let spec = null;
26
- if (node.rule.value === 'tab' && node.indentation.type !== 'tab') {
24
+ if (node.rule.value === 'tab' && indent.type !== 'tab') {
27
25
  spec = 'tab';
28
26
  }
29
- else if (typeof node.rule.value === 'number' && node.indentation.type !== 'space') {
27
+ else if (typeof node.rule.value === 'number' && indent.type !== 'space') {
30
28
  spec = 'space';
31
29
  }
32
30
  else if (typeof node.rule.value === 'number' &&
33
- node.indentation.type === 'space' &&
34
- node.indentation.width % node.rule.value) {
35
- spec = translate('{0} width spaces', `${node.rule.value}`);
31
+ indent.type === 'space' &&
32
+ indent.width % node.rule.value) {
33
+ spec = context.translate('{0} width spaces', `${node.rule.value}`);
36
34
  }
37
35
  if (spec) {
38
- const message = translate(`{0} ${ms} be {1}`, 'Indentation', spec);
39
- reports.push({
40
- severity: node.rule.severity,
36
+ const message = context.translate(`{0} ${ms} be {1}`, 'Indentation', spec);
37
+ context.report({
38
+ scope: node,
41
39
  message,
42
- line: node.indentation.line,
40
+ line: indent.line,
43
41
  col: 1,
44
- raw: node.indentation.raw,
42
+ raw: indent.raw,
45
43
  });
46
44
  return;
47
45
  }
@@ -55,41 +53,32 @@ exports.default = ml_core_1.createRule({
55
53
  }
56
54
  const parent = node.syntaxicalParentNode;
57
55
  if (parent) {
58
- const parentIndentWidth = parent.indentation ? parent.indentation.width : 0;
59
- const childIndentWidth = node.indentation.width;
56
+ const parentIndent = (0, ml_core_1.getIndent)(parent);
57
+ const parentIndentWidth = parentIndent ? parentIndent.width : 0;
58
+ const childIndentWidth = indent.width;
60
59
  const expectedWidth = node.rule.value === 'tab' ? 1 : node.rule.value;
61
60
  const diff = childIndentWidth - parentIndentWidth;
62
- // console.log({
63
- // [parent.raw]: parent.indentation ? parent.indentation.width : 0,
64
- // [node.raw]: node.indentation.width,
65
- // rule: node.rule,
66
- // parentIndentWidth,
67
- // childIndentWidth,
68
- // expectedWidth,
69
- // diff,
70
- // nested,
71
- // });
72
61
  if (nested === 'never') {
73
62
  if (diff !== 0) {
74
- const message = translate(diff < 1 ? 'Should increase indentation' : 'Should decrease indentation');
75
- reports.push({
76
- severity: node.rule.severity,
63
+ const message = context.translate(diff < 1 ? 'Should increase indentation' : 'Should decrease indentation');
64
+ context.report({
65
+ scope: node,
77
66
  message,
78
- line: node.indentation.line,
67
+ line: indent.line,
79
68
  col: 1,
80
- raw: node.indentation.raw,
69
+ raw: indent.raw,
81
70
  });
82
71
  }
83
72
  }
84
73
  else {
85
74
  if (diff !== expectedWidth) {
86
- const message = translate(diff < 1 ? 'Should increase indentation' : 'Should decrease indentation');
87
- reports.push({
88
- severity: node.rule.severity,
75
+ const message = context.translate(diff < 1 ? 'Should increase indentation' : 'Should decrease indentation');
76
+ context.report({
77
+ scope: node,
89
78
  message,
90
- line: node.indentation.line,
79
+ line: indent.line,
91
80
  col: 1,
92
- raw: node.indentation.raw,
81
+ raw: indent.raw,
93
82
  });
94
83
  }
95
84
  }
@@ -104,63 +93,53 @@ exports.default = ml_core_1.createRule({
104
93
  if (!closeTag.rule.option.alignment) {
105
94
  return;
106
95
  }
107
- if (!closeTag.indentation) {
96
+ const closeTagIndent = (0, ml_core_1.getIndent)(closeTag);
97
+ if (!closeTagIndent) {
108
98
  return;
109
99
  }
110
100
  if (startTag.endLine === closeTag.endLine) {
111
101
  return;
112
102
  }
113
- const endTagIndentationWidth = closeTag.indentation ? closeTag.indentation.width : 0;
114
- const startTagIndentationWidth = startTag.indentation ? startTag.indentation.width : 0;
115
- // console.log({
116
- // [`${startTag}`]: startTagIndentationWidth,
117
- // [`${closeTag}`]: endTagIndentationWidth,
118
- // });
103
+ const startTagIndent = (0, ml_core_1.getIndent)(startTag);
104
+ const endTagIndentationWidth = closeTagIndent ? closeTagIndent.width : 0;
105
+ const startTagIndentationWidth = startTagIndent ? startTagIndent.width : 0;
119
106
  if (startTagIndentationWidth !== endTagIndentationWidth) {
120
- const message = translate('Start tag and end tag indentation should align');
121
- reports.push({
122
- severity: closeTag.rule.severity,
107
+ const message = context.translate('Start tag and end tag indentation should align');
108
+ context.report({
109
+ scope: closeTag,
123
110
  message,
124
- line: closeTag.indentation ? closeTag.indentation.line : closeTag.startLine,
111
+ line: closeTagIndent ? closeTagIndent.line : closeTag.startLine,
125
112
  col: 1,
126
- raw: closeTag.indentation ? closeTag.indentation.raw : '',
113
+ raw: closeTagIndent ? closeTagIndent.raw : '',
127
114
  });
128
115
  }
129
116
  }
130
117
  });
131
- return reports;
132
118
  },
133
- async fix(document) {
119
+ async fix({ document }) {
134
120
  /**
135
121
  * Validate indent type and length.
136
122
  */
137
123
  await document.walk(async (node) => {
138
- if (!node.rule.disabled && node.indentation) {
139
- if (node.indentation.type !== 'none') {
124
+ const indent = (0, ml_core_1.getIndent)(node);
125
+ if (!node.rule.disabled && indent) {
126
+ if (indent.type !== 'none') {
140
127
  const spec = node.rule.value === 'tab' ? '\t' : ' ';
141
128
  const baseWidth = node.rule.value === 'tab' ? 4 : node.rule.value;
142
129
  let width;
143
130
  if (node.rule.value === 'tab') {
144
- width =
145
- node.indentation.type === 'tab'
146
- ? node.indentation.width
147
- : Math.ceil(node.indentation.width / baseWidth);
131
+ width = indent.type === 'tab' ? indent.width : Math.ceil(indent.width / baseWidth);
148
132
  }
149
133
  else {
150
134
  width =
151
- node.indentation.type === 'tab'
152
- ? node.indentation.width * baseWidth
153
- : Math.ceil(node.indentation.width / baseWidth) * baseWidth;
135
+ indent.type === 'tab'
136
+ ? indent.width * baseWidth
137
+ : Math.ceil(indent.width / baseWidth) * baseWidth;
154
138
  }
155
- const raw = node.indentation.raw;
139
+ const raw = indent.raw;
156
140
  const fixed = spec.repeat(width);
157
- // console.log({spec, width});
158
141
  if (raw !== fixed) {
159
- // console.log('step1', {
160
- // raw: space(raw),
161
- // fix: space(fixed),
162
- // });
163
- node.indentation.fix(fixed);
142
+ indent.fix(fixed);
164
143
  }
165
144
  }
166
145
  }
@@ -169,7 +148,8 @@ exports.default = ml_core_1.createRule({
169
148
  if (node.rule.disabled) {
170
149
  return;
171
150
  }
172
- if (node.indentation) {
151
+ const indent = (0, ml_core_1.getIndent)(node);
152
+ if (indent) {
173
153
  /**
174
154
  * Validate nested parent-children nodes.
175
155
  */
@@ -177,37 +157,28 @@ exports.default = ml_core_1.createRule({
177
157
  if (!nested) {
178
158
  return;
179
159
  }
180
- if (node.parentNode) {
181
- const parent = node.syntaxicalParentNode;
182
- // console.log(node.raw, parent);
183
- if (parent && parent.indentation) {
184
- const parentIndentWidth = parent.indentation.width;
185
- const childIndentWidth = node.indentation.width;
186
- const expectedWidth = node.rule.value === 'tab' ? 1 : node.rule.value;
187
- const diff = childIndentWidth - parentIndentWidth;
188
- // console.log({ parentIndentWidth, childIndentWidth, expectedWidth, diff });
189
- if (nested === 'never') {
190
- if (diff !== 0) {
191
- // const raw = node.indentation.raw;
192
- const fixed = parent.indentation.raw;
193
- // console.log('step2-A', {
194
- // raw: space(raw),
195
- // fix: space(fixed),
196
- // });
197
- node.indentation.fix(fixed);
198
- }
199
- }
200
- else {
201
- if (diff !== expectedWidth) {
202
- // const raw = node.indentation.raw;
203
- const fixed = (node.rule.value === 'tab' ? '\t' : ' ').repeat(parentIndentWidth + expectedWidth);
204
- // console.log('step2-B', {
205
- // raw: space(raw),
206
- // fix: space(fixed),
207
- // });
208
- node.indentation.fix(fixed);
209
- }
210
- }
160
+ const parent = node.syntaxicalParentNode;
161
+ if (!parent) {
162
+ return;
163
+ }
164
+ const parentIndent = (0, ml_core_1.getIndent)(parent);
165
+ if (!parentIndent) {
166
+ return;
167
+ }
168
+ const parentIndentWidth = parentIndent.width;
169
+ const childIndentWidth = indent.width;
170
+ const expectedWidth = node.rule.value === 'tab' ? 1 : node.rule.value;
171
+ const diff = childIndentWidth - parentIndentWidth;
172
+ if (nested === 'never') {
173
+ if (diff !== 0) {
174
+ const fixed = parentIndent.raw;
175
+ indent.fix(fixed);
176
+ }
177
+ }
178
+ else {
179
+ if (diff !== expectedWidth) {
180
+ const fixed = (node.rule.value === 'tab' ? '\t' : ' ').repeat(parentIndentWidth + expectedWidth);
181
+ indent.fix(fixed);
211
182
  }
212
183
  }
213
184
  }
@@ -222,22 +193,16 @@ exports.default = ml_core_1.createRule({
222
193
  if (!endTag.rule.option.alignment) {
223
194
  return;
224
195
  }
225
- if (endTag.indentation && endTag.startTag.indentation) {
226
- const endTagIndentationWidth = endTag.indentation.width;
227
- const startTagIndentationWidth = endTag.startTag.indentation.width;
196
+ const endTagIndent = (0, ml_core_1.getIndent)(endTag);
197
+ const startTagIndent = (0, ml_core_1.getIndent)(endTag.startTag);
198
+ if (endTagIndent && startTagIndent) {
199
+ const endTagIndentationWidth = endTagIndent.width;
200
+ const startTagIndentationWidth = startTagIndent.width;
228
201
  if (startTagIndentationWidth !== endTagIndentationWidth) {
229
- // const raw = endTag.indentation.raw;
230
- const fixed = endTag.startTag.indentation.raw;
231
- // console.log('step3', {
232
- // raw: space(raw),
233
- // fix: space(fixed),
234
- // });
235
- endTag.indentation.fix(fixed);
202
+ const fixed = startTagIndent.raw;
203
+ endTagIndent.fix(fixed);
236
204
  }
237
205
  }
238
206
  });
239
207
  },
240
208
  });
241
- // function space(str: string) {
242
- // return str.replace(/ /g, $0 => '•').replace(/\t/g, $0 => '→ ');
243
- // }
package/lib/index.d.ts CHANGED
@@ -1,25 +1,46 @@
1
- declare const _default: (import("packages/@markuplint/ml-core/lib").MLRule<boolean, import("./attr-spacing").AttrSpasingOptions> | import("packages/@markuplint/ml-core/lib").MLRule<boolean, null> | import("packages/@markuplint/ml-core/lib").MLRule<import("./class-naming").Value, null> | import("packages/@markuplint/ml-core/lib").MLRule<"always", {
2
- denyObsolateType: boolean;
3
- }> | import("packages/@markuplint/ml-core/lib").MLRule<import("./indentation").Value, import("./indentation").IndentationOptions> | import("packages/@markuplint/ml-core/lib").MLRule<true, {
4
- attrs?: Record<string, {
5
- enum: string[];
6
- } | {
7
- pattern: string;
8
- } | {
9
- type: import("packages/@markuplint/ml-spec/src").AttributeType;
10
- }> | undefined;
11
- ignoreAttrNamePrefix?: string | string[] | undefined;
12
- }> | import("packages/@markuplint/ml-core/lib").MLRule<boolean, {
13
- ignoreRoles: (("banner" | "main" | "complementary" | "contentinfo") | "form" | "navigation" | "region")[];
14
- labelEachArea: boolean;
15
- }> | import("packages/@markuplint/ml-core/lib").MLRule<import("packages/@markuplint/ml-spec/src").PermittedStructuresSchema[], {
16
- ignoreHasMutableChildren: boolean;
17
- }> | import("packages/@markuplint/ml-core/lib").MLRule<boolean, import("./required-h1").RequiredH1Options> | import("packages/@markuplint/ml-core/lib").MLRule<true, {
18
- checkingValue?: boolean | undefined;
19
- checkingDeprecatedProps?: boolean | undefined;
20
- permittedAriaRoles?: boolean | undefined;
21
- disallowSetImplicitRole?: boolean | undefined;
22
- disallowSetImplicitProps?: boolean | undefined;
23
- disallowDefaultValue?: boolean | undefined;
24
- }>)[];
1
+ declare const _default: {
2
+ 'attr-duplication': import("packages/@markuplint/ml-core/lib").RuleSeed<null, null>;
3
+ 'attr-equal-space-after': import("packages/@markuplint/ml-core/lib").RuleSeed<"always" | "never" | "always-single-line" | "never-single-line", null>;
4
+ 'attr-equal-space-before': import("packages/@markuplint/ml-core/lib").RuleSeed<"always" | "never" | "always-single-line" | "never-single-line", null>;
5
+ 'attr-spacing': import("packages/@markuplint/ml-core/lib").RuleSeed<boolean, import("./attr-spacing").AttrSpasingOptions>;
6
+ 'attr-value-quotes': import("packages/@markuplint/ml-core/lib").RuleSeed<import("./attr-value-quotes").Type, null>;
7
+ 'case-sensitive-attr-name': import("packages/@markuplint/ml-core/lib").RuleSeed<import("./case-sensitive-attr-name").Value, null>;
8
+ 'case-sensitive-tag-name': import("packages/@markuplint/ml-core/lib").RuleSeed<import("./case-sensitive-tag-name").Value, null>;
9
+ 'character-reference': import("packages/@markuplint/ml-core/lib").RuleSeed<boolean, null>;
10
+ 'class-naming': import("packages/@markuplint/ml-core/lib").RuleSeed<import("./class-naming").Value, null>;
11
+ 'deprecated-attr': import("packages/@markuplint/ml-core/lib").RuleSeed<null, null>;
12
+ 'deprecated-element': import("packages/@markuplint/ml-core/lib").RuleSeed<null, null>;
13
+ doctype: import("packages/@markuplint/ml-core/lib").RuleSeed<"always", {
14
+ denyObsolateType: boolean;
15
+ }>;
16
+ 'id-duplication': import("packages/@markuplint/ml-core/lib").RuleSeed<null, null>;
17
+ indentation: import("packages/@markuplint/ml-core/lib").RuleSeed<import("./indentation").Value, import("./indentation").IndentationOptions>;
18
+ 'invalid-attr': import("packages/@markuplint/ml-core/lib").RuleSeed<true, {
19
+ attrs?: Record<string, {
20
+ enum: string[];
21
+ } | {
22
+ pattern: string;
23
+ } | {
24
+ type: import("packages/@markuplint/ml-spec/lib").AttributeType;
25
+ }> | undefined;
26
+ ignoreAttrNamePrefix?: string | string[] | undefined;
27
+ }>;
28
+ 'landmark-roles': import("packages/@markuplint/ml-core/lib").RuleSeed<boolean, {
29
+ ignoreRoles?: (("banner" | "main" | "complementary" | "contentinfo") | "form" | "navigation" | "region")[] | undefined;
30
+ labelEachArea?: boolean | undefined;
31
+ }>;
32
+ 'permitted-contents': import("packages/@markuplint/ml-core/lib").RuleSeed<import("packages/@markuplint/ml-spec/lib").PermittedStructuresSchema[], {
33
+ ignoreHasMutableChildren: boolean;
34
+ }>;
35
+ 'required-attr': import("packages/@markuplint/ml-core/lib").RuleSeed<string | string[], null>;
36
+ 'required-h1': import("packages/@markuplint/ml-core/lib").RuleSeed<boolean, import("./required-h1").RequiredH1Options>;
37
+ 'wai-aria': import("packages/@markuplint/ml-core/lib").RuleSeed<true, {
38
+ checkingValue?: boolean | undefined;
39
+ checkingDeprecatedProps?: boolean | undefined;
40
+ permittedAriaRoles?: boolean | undefined;
41
+ disallowSetImplicitRole?: boolean | undefined;
42
+ disallowSetImplicitProps?: boolean | undefined;
43
+ disallowDefaultValue?: boolean | undefined;
44
+ }>;
45
+ };
25
46
  export default _default;