@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/index.js CHANGED
@@ -1,45 +1,45 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- const attr_duplication_1 = tslib_1.__importDefault(require("./attr-duplication"));
5
- const attr_equal_space_after_1 = tslib_1.__importDefault(require("./attr-equal-space-after"));
6
- const attr_equal_space_before_1 = tslib_1.__importDefault(require("./attr-equal-space-before"));
7
- const attr_spacing_1 = tslib_1.__importDefault(require("./attr-spacing"));
8
- const attr_value_quotes_1 = tslib_1.__importDefault(require("./attr-value-quotes"));
9
- const case_sensitive_attr_name_1 = tslib_1.__importDefault(require("./case-sensitive-attr-name"));
10
- const case_sensitive_tag_name_1 = tslib_1.__importDefault(require("./case-sensitive-tag-name"));
11
- const character_reference_1 = tslib_1.__importDefault(require("./character-reference"));
12
- const class_naming_1 = tslib_1.__importDefault(require("./class-naming"));
13
- const deprecated_attr_1 = tslib_1.__importDefault(require("./deprecated-attr"));
14
- const deprecated_element_1 = tslib_1.__importDefault(require("./deprecated-element"));
15
- const doctype_1 = tslib_1.__importDefault(require("./doctype"));
16
- const id_duplication_1 = tslib_1.__importDefault(require("./id-duplication"));
17
- const indentation_1 = tslib_1.__importDefault(require("./indentation"));
18
- const invalid_attr_1 = tslib_1.__importDefault(require("./invalid-attr"));
19
- const landmark_roles_1 = tslib_1.__importDefault(require("./landmark-roles"));
20
- const permitted_contents_1 = tslib_1.__importDefault(require("./permitted-contents"));
21
- const required_attr_1 = tslib_1.__importDefault(require("./required-attr"));
22
- const required_h1_1 = tslib_1.__importDefault(require("./required-h1"));
23
- const wai_aria_1 = tslib_1.__importDefault(require("./wai-aria"));
24
- exports.default = [
25
- attr_duplication_1.default,
26
- attr_equal_space_after_1.default,
27
- attr_equal_space_before_1.default,
28
- attr_spacing_1.default,
29
- attr_value_quotes_1.default,
30
- case_sensitive_attr_name_1.default,
31
- case_sensitive_tag_name_1.default,
32
- character_reference_1.default,
33
- class_naming_1.default,
34
- deprecated_attr_1.default,
35
- deprecated_element_1.default,
36
- doctype_1.default,
37
- id_duplication_1.default,
38
- indentation_1.default,
39
- invalid_attr_1.default,
40
- landmark_roles_1.default,
41
- permitted_contents_1.default,
42
- required_attr_1.default,
43
- required_h1_1.default,
44
- wai_aria_1.default,
45
- ];
4
+ const attr_duplication_1 = (0, tslib_1.__importDefault)(require("./attr-duplication"));
5
+ const attr_equal_space_after_1 = (0, tslib_1.__importDefault)(require("./attr-equal-space-after"));
6
+ const attr_equal_space_before_1 = (0, tslib_1.__importDefault)(require("./attr-equal-space-before"));
7
+ const attr_spacing_1 = (0, tslib_1.__importDefault)(require("./attr-spacing"));
8
+ const attr_value_quotes_1 = (0, tslib_1.__importDefault)(require("./attr-value-quotes"));
9
+ const case_sensitive_attr_name_1 = (0, tslib_1.__importDefault)(require("./case-sensitive-attr-name"));
10
+ const case_sensitive_tag_name_1 = (0, tslib_1.__importDefault)(require("./case-sensitive-tag-name"));
11
+ const character_reference_1 = (0, tslib_1.__importDefault)(require("./character-reference"));
12
+ const class_naming_1 = (0, tslib_1.__importDefault)(require("./class-naming"));
13
+ const deprecated_attr_1 = (0, tslib_1.__importDefault)(require("./deprecated-attr"));
14
+ const deprecated_element_1 = (0, tslib_1.__importDefault)(require("./deprecated-element"));
15
+ const doctype_1 = (0, tslib_1.__importDefault)(require("./doctype"));
16
+ const id_duplication_1 = (0, tslib_1.__importDefault)(require("./id-duplication"));
17
+ const indentation_1 = (0, tslib_1.__importDefault)(require("./indentation"));
18
+ const invalid_attr_1 = (0, tslib_1.__importDefault)(require("./invalid-attr"));
19
+ const landmark_roles_1 = (0, tslib_1.__importDefault)(require("./landmark-roles"));
20
+ const permitted_contents_1 = (0, tslib_1.__importDefault)(require("./permitted-contents"));
21
+ const required_attr_1 = (0, tslib_1.__importDefault)(require("./required-attr"));
22
+ const required_h1_1 = (0, tslib_1.__importDefault)(require("./required-h1"));
23
+ const wai_aria_1 = (0, tslib_1.__importDefault)(require("./wai-aria"));
24
+ exports.default = {
25
+ 'attr-duplication': attr_duplication_1.default,
26
+ 'attr-equal-space-after': attr_equal_space_after_1.default,
27
+ 'attr-equal-space-before': attr_equal_space_before_1.default,
28
+ 'attr-spacing': attr_spacing_1.default,
29
+ 'attr-value-quotes': attr_value_quotes_1.default,
30
+ 'case-sensitive-attr-name': case_sensitive_attr_name_1.default,
31
+ 'case-sensitive-tag-name': case_sensitive_tag_name_1.default,
32
+ 'character-reference': character_reference_1.default,
33
+ 'class-naming': class_naming_1.default,
34
+ 'deprecated-attr': deprecated_attr_1.default,
35
+ 'deprecated-element': deprecated_element_1.default,
36
+ doctype: doctype_1.default,
37
+ 'id-duplication': id_duplication_1.default,
38
+ indentation: indentation_1.default,
39
+ 'invalid-attr': invalid_attr_1.default,
40
+ 'landmark-roles': landmark_roles_1.default,
41
+ 'permitted-contents': permitted_contents_1.default,
42
+ 'required-attr': required_attr_1.default,
43
+ 'required-h1': required_h1_1.default,
44
+ 'wai-aria': wai_aria_1.default,
45
+ };
@@ -1,4 +1,4 @@
1
- import { AttributeType } from '@markuplint/ml-spec/src';
1
+ import type { AttributeType } from '@markuplint/ml-spec';
2
2
  declare type Option = {
3
3
  attrs?: Record<string, Rule>;
4
4
  ignoreAttrNamePrefix?: string | string[];
@@ -10,5 +10,5 @@ declare type Rule = {
10
10
  } | {
11
11
  type: AttributeType;
12
12
  };
13
- declare const _default: import("@markuplint/ml-core").MLRule<true, Option>;
13
+ declare const _default: import("@markuplint/ml-core").RuleSeed<true, Option>;
14
14
  export default _default;
@@ -1,34 +1,32 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ml_core_1 = require("@markuplint/ml-core");
4
+ const attr_check_1 = require("../attr-check");
4
5
  const helpers_1 = require("../helpers");
5
- const type_check_1 = require("../type-check");
6
- exports.default = ml_core_1.createRule({
7
- name: 'invalid-attr',
8
- defaultLevel: 'error',
6
+ exports.default = (0, ml_core_1.createRule)({
9
7
  defaultValue: true,
10
8
  defaultOptions: {},
11
- async verify(document, translate) {
12
- const reports = [];
9
+ async verify({ document, report, t }) {
13
10
  await document.walkOn('Element', async (node) => {
14
- const attrSpecs = helpers_1.getAttrSpecs(node.nodeName, document.specs);
11
+ const attrSpecs = (0, helpers_1.getAttrSpecs)(node.nameWithNS, document.specs);
15
12
  for (const attr of node.attributes) {
16
13
  if (attr.attrType === 'html-attr' && attr.isDirective) {
17
14
  continue;
18
15
  }
19
16
  const attrName = attr.getName();
20
17
  const name = attrName.potential;
21
- if (attr.attrType === 'html-attr' && attr.isInvalid) {
22
- const candidate = attr.candidate;
23
- const message = `The "${attrName.raw}" attribute is not allowed.` +
24
- (candidate ? ` Did you mean "${candidate}"?` : '');
25
- reports.push({
26
- severity: node.rule.severity,
18
+ if (!node.isCustomElement && attr.attrType === 'html-attr' && attr.candidate) {
19
+ const message = t('{0} is {1:c}', t('the "{0}" {1}', attrName.raw, 'attribute'), 'disallowed') +
20
+ t('. ') +
21
+ t('Did you mean "{0}"?', attr.candidate);
22
+ report({
23
+ scope: node,
27
24
  message: message,
28
25
  line: attrName.line,
29
26
  col: attrName.col,
30
27
  raw: attrName.raw,
31
28
  });
29
+ continue;
32
30
  }
33
31
  const attrValue = attr.getValue();
34
32
  const value = attrValue.raw;
@@ -44,33 +42,34 @@ exports.default = ml_core_1.createRule({
44
42
  const customRule = node.rule.option.attrs ? node.rule.option.attrs[name] : null;
45
43
  if (customRule) {
46
44
  if ('enum' in customRule) {
47
- invalid = type_check_1.typeCheck(name.toLowerCase(), value, true, {
45
+ invalid = (0, attr_check_1.attrCheck)(t, name.toLowerCase(), value, true, {
48
46
  name,
49
- type: 'String',
50
- enum: customRule.enum,
47
+ type: {
48
+ enum: customRule.enum,
49
+ },
51
50
  description: '',
52
51
  });
53
52
  }
54
53
  else if ('pattern' in customRule) {
55
- if (!helpers_1.match(value, customRule.pattern)) {
54
+ if (!(0, helpers_1.match)(value, customRule.pattern)) {
56
55
  invalid = {
57
56
  invalidType: 'invalid-value',
58
- message: `The "${name}" attribute expect custom pattern "${customRule.pattern}"`,
57
+ message: t('{0} is unmatched with the below patterns: {1}', t('the "{0}" {1}', name, 'attribute'), customRule.pattern),
59
58
  };
60
59
  }
61
60
  }
62
61
  else if ('type' in customRule) {
63
- invalid = type_check_1.typeCheck(name, value, true, { name, type: customRule.type, description: '' });
62
+ invalid = (0, attr_check_1.attrCheck)(t, name, value, true, { name, type: customRule.type, description: '' });
64
63
  }
65
64
  }
66
65
  else if (!node.isCustomElement && attrSpecs) {
67
- invalid = helpers_1.isValidAttr(name, value, (attr.attrType === 'html-attr' && attr.isDynamicValue) || false, node, attrSpecs);
66
+ invalid = (0, helpers_1.isValidAttr)(t, name, value, (attr.attrType === 'html-attr' && attr.isDynamicValue) || false, node, attrSpecs);
68
67
  }
69
68
  if (invalid) {
70
69
  switch (invalid.invalidType) {
71
70
  case 'invalid-value': {
72
- reports.push({
73
- severity: node.rule.severity,
71
+ report({
72
+ scope: node,
74
73
  message: invalid.message,
75
74
  line: attrValue.line,
76
75
  col: attrValue.col,
@@ -79,8 +78,8 @@ exports.default = ml_core_1.createRule({
79
78
  break;
80
79
  }
81
80
  case 'non-existent': {
82
- reports.push({
83
- severity: node.rule.severity,
81
+ report({
82
+ scope: node,
84
83
  message: invalid.message,
85
84
  line: attrName.line,
86
85
  col: attrName.col,
@@ -91,6 +90,5 @@ exports.default = ml_core_1.createRule({
91
90
  }
92
91
  }
93
92
  });
94
- return reports;
95
93
  },
96
94
  });
@@ -1,8 +1,8 @@
1
1
  declare type Options = {
2
- ignoreRoles: Roles[];
3
- labelEachArea: boolean;
2
+ ignoreRoles?: Roles[];
3
+ labelEachArea?: boolean;
4
4
  };
5
5
  declare type TopLevelRoles = 'banner' | 'main' | 'complementary' | 'contentinfo';
6
6
  declare type Roles = TopLevelRoles | 'form' | 'navigation' | 'region';
7
- declare const _default: import("@markuplint/ml-core").MLRule<boolean, Options>;
7
+ declare const _default: import("@markuplint/ml-core").RuleSeed<boolean, Options>;
8
8
  export default _default;
@@ -11,19 +11,18 @@ const selectors = {
11
11
  region: ['[role="region"]', 'section[aria-labelledby]', 'section[aria-label]', 'section[title]'],
12
12
  };
13
13
  const topLevelRoles = ['banner', 'main', 'complementary', 'contentinfo'];
14
- exports.default = ml_core_1.createRule({
15
- name: 'landmark-roles',
16
- defaultLevel: 'warning',
14
+ exports.default = (0, ml_core_1.createRule)({
15
+ defaultServerity: 'warning',
17
16
  defaultValue: true,
18
17
  defaultOptions: {
19
18
  ignoreRoles: [],
20
19
  labelEachArea: true,
21
20
  },
22
- async verify(document, translate) {
21
+ async verify({ document, report, t }) {
22
+ var _a;
23
23
  if (document.isFragment) {
24
- return [];
24
+ return;
25
25
  }
26
- const reports = [];
27
26
  const roles = {
28
27
  complementary: document.matchNodes(selectors.complementary.join(',')),
29
28
  contentinfo: document.matchNodes(selectors.contentinfo.join(',')),
@@ -74,16 +73,13 @@ exports.default = ml_core_1.createRule({
74
73
  if (el.rule.disabled) {
75
74
  continue;
76
75
  }
77
- if (el.rule.option.ignoreRoles.includes(role)) {
76
+ if ((_a = el.rule.option.ignoreRoles) === null || _a === void 0 ? void 0 : _a.includes(role)) {
78
77
  continue;
79
78
  }
80
79
  if (el.isDescendantByUUIDList(uuidList)) {
81
- reports.push({
82
- severity: el.rule.severity,
83
- message: translate('{0} should be {1}', role, 'top level'),
84
- line: el.startLine,
85
- col: el.startCol,
86
- raw: el.raw,
80
+ report({
81
+ scope: el,
82
+ message: t('{0} should be {1}', t('the "{0}" {1}', role, 'role'), 'top level'),
87
83
  });
88
84
  }
89
85
  }
@@ -102,17 +98,13 @@ exports.default = ml_core_1.createRule({
102
98
  continue;
103
99
  }
104
100
  if (!hasLabel(el)) {
105
- reports.push({
106
- severity: el.rule.severity,
107
- message: translate('Should have a unique label because {0} landmarks were markup more than once on a page', role),
108
- line: el.startLine,
109
- col: el.startCol,
110
- raw: el.raw,
101
+ report({
102
+ scope: el,
103
+ message: t('Require {0}', t('unique {0}', 'accessible name')),
111
104
  });
112
105
  }
113
106
  }
114
107
  }
115
- return reports;
116
108
  },
117
109
  });
118
110
  function landmarkRoleElementUUIDList(roleset) {
@@ -1,6 +1,6 @@
1
- import { PermittedStructuresSchema } from '@markuplint/ml-spec';
1
+ import type { PermittedStructuresSchema } from '@markuplint/ml-spec';
2
2
  declare type Options = {
3
3
  ignoreHasMutableChildren: boolean;
4
4
  };
5
- declare const _default: import("@markuplint/ml-core").MLRule<PermittedStructuresSchema[], Options>;
5
+ declare const _default: import("@markuplint/ml-core").RuleSeed<PermittedStructuresSchema[], Options>;
6
6
  export default _default;
@@ -2,18 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const ml_core_1 = require("@markuplint/ml-core");
5
- const permitted_content_spec_to_regexp_1 = tslib_1.__importDefault(require("./permitted-content.spec-to-regexp"));
6
5
  const helpers_1 = require("../helpers");
7
- const unfold_content_models_to_tags_1 = tslib_1.__importDefault(require("./unfold-content-models-to-tags"));
6
+ const permitted_content_spec_to_regexp_1 = (0, tslib_1.__importDefault)(require("./permitted-content.spec-to-regexp"));
7
+ const unfold_content_models_to_tags_1 = (0, tslib_1.__importDefault)(require("./unfold-content-models-to-tags"));
8
8
  const expMapOnNodeId = new Map();
9
- exports.default = ml_core_1.createRule({
10
- name: 'permitted-contents',
9
+ exports.default = (0, ml_core_1.createRule)({
11
10
  defaultValue: [],
12
11
  defaultOptions: {
13
12
  ignoreHasMutableChildren: true,
14
13
  },
15
- async verify(document, translate) {
16
- const reports = [];
14
+ async verify({ document, report, t }) {
17
15
  let idCounter = 0;
18
16
  await document.walkOn('Element', async (node) => {
19
17
  var _a;
@@ -23,17 +21,15 @@ exports.default = ml_core_1.createRule({
23
21
  if (node.rule.option.ignoreHasMutableChildren && node.hasMutableChildren()) {
24
22
  return;
25
23
  }
24
+ const specType = node.ns === 'html' ? 'HTML' : node.ns === 'svg' ? 'SVG' : 'Any Language';
26
25
  const childNodes = node.getChildElementsAndTextNodeWithoutWhitespaces();
27
- const spec = !node.isCustomElement && ((_a = helpers_1.htmlSpec(node.nodeName)) === null || _a === void 0 ? void 0 : _a.permittedStructures);
26
+ const spec = !node.isCustomElement && ((_a = (0, helpers_1.htmlSpec)(node.nameWithNS)) === null || _a === void 0 ? void 0 : _a.permittedStructures);
28
27
  const expGen = new permitted_content_spec_to_regexp_1.default(idCounter++);
29
28
  if (spec) {
30
29
  if (spec.ancestor && !node.closest(spec.ancestor)) {
31
- reports.push({
32
- severity: node.rule.severity,
33
- message: translate('The {0} element must be descendant of the {1} element', node.nodeName, spec.ancestor),
34
- line: node.startLine,
35
- col: node.startCol,
36
- raw: node.raw,
30
+ report({
31
+ scope: node,
32
+ message: t('{0} must be {1}', t('the "{0}" {1}', node.nodeName, 'element'), t('{0} of {1}', 'descendant', t('the "{0}" {1}', spec.ancestor, 'element'))),
37
33
  });
38
34
  return;
39
35
  }
@@ -50,12 +46,15 @@ exports.default = ml_core_1.createRule({
50
46
  if (matched) {
51
47
  try {
52
48
  const parentExp = getRegExpFromParentNode(node, expGen);
53
- const exp = expGen.specToRegExp(conditional.contents, parentExp);
54
- const conditionalResult = match(exp, childNodes, false);
49
+ const exp = expGen.specToRegExp(conditional.contents, parentExp, node.ns);
50
+ const conditionalResult = match(exp, childNodes, node.ns, false);
55
51
  if (!conditionalResult) {
56
- reports.push({
57
- severity: node.rule.severity,
58
- message: translate('Invalid content of the {0} element in {1}', node.nodeName, 'the HTML specification'),
52
+ const message = t('{0} is {1:c}', t('{0} of {1}', t('the {0}', 'content'), t('the "{0}" {1}', node.nodeName, 'element')), 'invalid');
53
+ report({
54
+ scope: node,
55
+ message: specType !== 'Any Language'
56
+ ? t('{0} according to {1}', message, `the ${specType} specification`)
57
+ : message,
59
58
  line: node.startLine,
60
59
  col: node.startCol,
61
60
  raw: node.raw,
@@ -64,8 +63,13 @@ exports.default = ml_core_1.createRule({
64
63
  }
65
64
  }
66
65
  catch (e) {
67
- // eslint-disable-next-line no-console
68
- console.warn(node.raw, 'conditional', conditional, e.message);
66
+ if (e instanceof Error) {
67
+ // eslint-disable-next-line no-console
68
+ console.warn(node.raw, 'conditional', conditional, e.message);
69
+ }
70
+ else {
71
+ throw e;
72
+ }
69
73
  }
70
74
  }
71
75
  }
@@ -73,20 +77,25 @@ exports.default = ml_core_1.createRule({
73
77
  if (!matched) {
74
78
  try {
75
79
  const exp = getRegExpFromNode(node, expGen);
76
- const specResult = match(exp, childNodes, false);
80
+ const specResult = match(exp, childNodes, node.ns, false);
77
81
  if (!specResult) {
78
- reports.push({
79
- severity: node.rule.severity,
80
- message: translate('Invalid content of the {0} element in {1}', node.nodeName, 'the HTML specification'),
81
- line: node.startLine,
82
- col: node.startCol,
83
- raw: node.raw,
82
+ const message = t('{0} is {1:c}', t('{0} of {1}', t('the {0}', 'content'), t('the "{0}" {1}', node.nodeName, 'element')), 'invalid');
83
+ report({
84
+ scope: node,
85
+ message: specType !== 'Any Language'
86
+ ? t('{0} according to {1}', message, `the ${specType} specification`)
87
+ : message,
84
88
  });
85
89
  }
86
90
  }
87
91
  catch (e) {
88
- // eslint-disable-next-line no-console
89
- console.warn(node.raw, 'HTML Spec', e.message);
92
+ if (e instanceof Error) {
93
+ // eslint-disable-next-line no-console
94
+ console.warn(node.raw, 'HTML Spec', e.message);
95
+ }
96
+ else {
97
+ throw e;
98
+ }
90
99
  }
91
100
  }
92
101
  }
@@ -96,13 +105,13 @@ exports.default = ml_core_1.createRule({
96
105
  }
97
106
  const parentExp = getRegExpFromParentNode(node, expGen);
98
107
  try {
99
- const exp = expGen.specToRegExp(rule.contents, parentExp);
108
+ const exp = expGen.specToRegExp(rule.contents, parentExp, node.ns);
100
109
  // Evaluate the custom element if the optional schema.
101
- const r = match(exp, childNodes, node.isCustomElement);
110
+ const r = match(exp, childNodes, node.ns, node.isCustomElement);
102
111
  if (!r) {
103
- reports.push({
104
- severity: node.rule.severity,
105
- message: translate('Invalid content of the {0} element in {1}', node.nodeName, 'settings'),
112
+ report({
113
+ scope: node,
114
+ message: t('{0} is {1:c}', t('{0} of {1}', t('the {0}', 'content'), t('the "{0}" {1}', node.nodeName, 'element')), 'invalid'),
106
115
  line: node.startLine,
107
116
  col: node.startCol,
108
117
  raw: node.raw,
@@ -111,22 +120,31 @@ exports.default = ml_core_1.createRule({
111
120
  }
112
121
  }
113
122
  catch (e) {
114
- // eslint-disable-next-line no-console
115
- console.warn(node.raw, 'rule', rule, e.message);
123
+ if (e instanceof Error) {
124
+ // eslint-disable-next-line no-console
125
+ console.warn(node.raw, 'rule', rule, e.message);
126
+ }
127
+ else {
128
+ throw e;
129
+ }
116
130
  }
117
131
  }
118
132
  });
119
133
  expMapOnNodeId.clear();
120
- return reports;
121
134
  },
122
135
  });
123
- function normalization(nodes, evalCustomElement) {
136
+ function normalization(nodes, ownNS, evalCustomElement) {
124
137
  return nodes
125
138
  .map(node => {
126
139
  if (!evalCustomElement && node.type === 'Element' && node.isCustomElement) {
127
140
  return '';
128
141
  }
129
- return `<${node.type === 'Element' ? node.nodeName : '#text'}>`;
142
+ if (node.type !== 'Element') {
143
+ return '<#text>';
144
+ }
145
+ ownNS = ownNS || 'html';
146
+ const name = node.nameWithNS.replace(new RegExp(`^${ownNS}:`), '');
147
+ return `<${name}>`;
130
148
  })
131
149
  .join('');
132
150
  }
@@ -137,9 +155,9 @@ function getRegExpFromNode(node, expGen) {
137
155
  return expMapOnNodeId.get(node.uuid);
138
156
  }
139
157
  const parentExp = node.parentNode ? getRegExpFromNode(node.parentNode, expGen) : null;
140
- const spec = !node.isCustomElement && ((_a = helpers_1.htmlSpec(node.nodeName)) === null || _a === void 0 ? void 0 : _a.permittedStructures);
158
+ const spec = !node.isCustomElement && ((_a = (0, helpers_1.htmlSpec)(node.nameWithNS || node.nodeName.toLowerCase())) === null || _a === void 0 ? void 0 : _a.permittedStructures);
141
159
  const contentRule = spec ? spec.contents : true;
142
- const exp = expGen.specToRegExp(contentRule, parentExp);
160
+ const exp = expGen.specToRegExp(contentRule, parentExp, node.ns || null);
143
161
  expMapOnNodeId.set(node.uuid, exp);
144
162
  return exp;
145
163
  }
@@ -148,8 +166,8 @@ function getRegExpFromParentNode(node, expGen) {
148
166
  const parentExp = node.parentNode ? getRegExpFromNode(node.parentNode, expGen) : null;
149
167
  return parentExp;
150
168
  }
151
- function match(exp, childNodes, evalCustomElement) {
152
- const target = normalization(childNodes, evalCustomElement);
169
+ function match(exp, childNodes, ownNS, evalCustomElement) {
170
+ const target = normalization(childNodes, ownNS, evalCustomElement);
153
171
  const result = exp.exec(target);
154
172
  if (!result) {
155
173
  return false;
@@ -170,7 +188,7 @@ function match(exp, childNodes, evalCustomElement) {
170
188
  switch (type) {
171
189
  case 'ACM': {
172
190
  const [model, tag] = _selector;
173
- const selectors = unfold_content_models_to_tags_1.default(`#${model}`).filter(selector => {
191
+ const selectors = (0, unfold_content_models_to_tags_1.default)(`#${model}`).filter(selector => {
174
192
  const [, tagName] = /^([^[\]]+)(?:\[[^\]]+\])?$/.exec(selector) || [];
175
193
  return tagName.toLowerCase() === tag.toLowerCase();
176
194
  });
@@ -203,7 +221,7 @@ function match(exp, childNodes, evalCustomElement) {
203
221
  : null;
204
222
  _selector.forEach(content => {
205
223
  if (content[0] === '_') {
206
- unfold_content_models_to_tags_1.default(content.replace('_', '#')).forEach(tag => contents.add(tag));
224
+ (0, unfold_content_models_to_tags_1.default)(content.replace('_', '#')).forEach(tag => contents.add(tag));
207
225
  return;
208
226
  }
209
227
  contents.add(content);
@@ -1,9 +1,9 @@
1
- import { PermittedContent } from '@markuplint/ml-spec';
1
+ import type { PermittedContent } from '@markuplint/ml-spec';
2
2
  export default class ExpGenerator {
3
3
  private _id;
4
4
  private _idCounter;
5
5
  constructor(_id: number);
6
- specToRegExp(contentRule: PermittedContent[] | boolean, parentExp?: RegExp | null): RegExp;
6
+ specToRegExp(contentRule: PermittedContent[] | boolean, parentExp?: RegExp | null, ownNS?: string | null): RegExp;
7
7
  private _toPattern;
8
8
  private _interleavePattern;
9
9
  private _targetTags;