@markuplint/ml-spec 4.10.1 → 5.0.0-alpha.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.
Files changed (111) hide show
  1. package/ARCHITECTURE.ja.md +267 -0
  2. package/ARCHITECTURE.md +267 -0
  3. package/CHANGELOG.md +20 -2
  4. package/README.md +6 -188
  5. package/SKILL.md +116 -0
  6. package/docs/aria-algorithms.ja.md +798 -0
  7. package/docs/aria-algorithms.md +800 -0
  8. package/docs/html-algorithms.ja.md +469 -0
  9. package/docs/html-algorithms.md +469 -0
  10. package/docs/maintenance.ja.md +331 -0
  11. package/docs/maintenance.md +331 -0
  12. package/docs/spec-resolution.ja.md +568 -0
  13. package/docs/spec-resolution.md +580 -0
  14. package/docs/type-definitions.ja.md +565 -0
  15. package/docs/type-definitions.md +565 -0
  16. package/lib/algorithm/aria/accname/__tests__/test-helpers.d.ts +45 -0
  17. package/lib/algorithm/aria/accname/__tests__/test-helpers.js +120 -0
  18. package/lib/algorithm/aria/accname/aria-steps.d.ts +51 -0
  19. package/lib/algorithm/aria/accname/aria-steps.js +104 -0
  20. package/lib/algorithm/aria/accname/compute.d.ts +51 -0
  21. package/lib/algorithm/aria/accname/compute.js +101 -0
  22. package/lib/algorithm/aria/accname/element-names.d.ts +36 -0
  23. package/lib/algorithm/aria/accname/element-names.js +342 -0
  24. package/lib/algorithm/aria/accname/helpers.d.ts +98 -0
  25. package/lib/algorithm/aria/accname/helpers.js +330 -0
  26. package/lib/algorithm/aria/accname/index.d.ts +4 -0
  27. package/lib/algorithm/aria/accname/index.js +3 -0
  28. package/lib/algorithm/aria/accname/label-steps.d.ts +25 -0
  29. package/lib/algorithm/aria/accname/label-steps.js +66 -0
  30. package/lib/algorithm/aria/accname/svg-helpers.d.ts +17 -0
  31. package/lib/algorithm/aria/accname/svg-helpers.js +30 -0
  32. package/lib/algorithm/aria/accname/types.d.ts +70 -0
  33. package/lib/algorithm/aria/accname/types.js +2 -0
  34. package/lib/algorithm/aria/accname-computation.d.ts +19 -1
  35. package/lib/algorithm/aria/accname-computation.js +136 -6
  36. package/lib/algorithm/aria/aria-specs.d.ts +8 -0
  37. package/lib/algorithm/aria/aria-specs.js +7 -0
  38. package/lib/algorithm/aria/get-aria.d.ts +12 -0
  39. package/lib/algorithm/aria/get-aria.js +42 -4
  40. package/lib/algorithm/aria/get-computed-aria-props.d.ts +22 -0
  41. package/lib/algorithm/aria/get-computed-aria-props.js +10 -0
  42. package/lib/algorithm/aria/get-computed-role.d.ts +12 -0
  43. package/lib/algorithm/aria/get-computed-role.js +118 -26
  44. package/lib/algorithm/aria/get-explicit-role.d.ts +12 -0
  45. package/lib/algorithm/aria/get-explicit-role.js +12 -0
  46. package/lib/algorithm/aria/get-implicit-role.d.ts +18 -0
  47. package/lib/algorithm/aria/get-implicit-role.js +18 -0
  48. package/lib/algorithm/aria/get-non-presentational-ancestor.d.ts +12 -0
  49. package/lib/algorithm/aria/get-non-presentational-ancestor.js +14 -2
  50. package/lib/algorithm/aria/get-permitted-roles-spec.d.ts +8 -4
  51. package/lib/algorithm/aria/get-permitted-roles-spec.js +19 -6
  52. package/lib/algorithm/aria/get-permitted-roles.d.ts +9 -0
  53. package/lib/algorithm/aria/get-permitted-roles.js +9 -0
  54. package/lib/algorithm/aria/get-role-spec.d.ts +11 -0
  55. package/lib/algorithm/aria/get-role-spec.js +21 -3
  56. package/lib/algorithm/aria/has-required-owned-elements.d.ts +24 -0
  57. package/lib/algorithm/aria/has-required-owned-elements.js +40 -14
  58. package/lib/algorithm/aria/is-exposed.d.ts +7 -4
  59. package/lib/algorithm/aria/is-exposed.js +7 -4
  60. package/lib/algorithm/aria/is-presentational.d.ts +32 -0
  61. package/lib/algorithm/aria/is-presentational.js +39 -0
  62. package/lib/algorithm/aria/matches-context-role.d.ts +19 -0
  63. package/lib/algorithm/aria/matches-context-role.js +46 -2
  64. package/lib/algorithm/html/content-model-category-to-tag-names.d.ts +9 -0
  65. package/lib/algorithm/html/content-model-category-to-tag-names.js +10 -1
  66. package/lib/algorithm/html/get-content-model.d.ts +12 -1
  67. package/lib/algorithm/html/get-content-model.js +14 -6
  68. package/lib/algorithm/html/get-selectors-by-content-model-category.d.ts +8 -0
  69. package/lib/algorithm/html/get-selectors-by-content-model-category.js +8 -0
  70. package/lib/algorithm/html/is-nothing-content-model.d.ts +7 -0
  71. package/lib/algorithm/html/is-nothing-content-model.js +7 -0
  72. package/lib/algorithm/html/is-palpable-elements.d.ts +13 -0
  73. package/lib/algorithm/html/is-palpable-elements.js +13 -0
  74. package/lib/algorithm/html/is-void-element.d.ts +9 -0
  75. package/lib/algorithm/html/is-void-element.js +9 -0
  76. package/lib/algorithm/html/may-be-focusable.d.ts +10 -0
  77. package/lib/algorithm/html/may-be-focusable.js +10 -0
  78. package/lib/const/accname.d.ts +29 -0
  79. package/lib/const/accname.js +76 -0
  80. package/lib/const/dom.d.ts +8 -0
  81. package/lib/const/dom.js +8 -0
  82. package/lib/const/index.d.ts +2 -0
  83. package/lib/const/index.js +2 -0
  84. package/lib/index.d.ts +3 -0
  85. package/lib/index.js +4 -0
  86. package/lib/types/index.d.ts +119 -0
  87. package/lib/utils/aria-version.d.ts +6 -0
  88. package/lib/utils/aria-version.js +6 -0
  89. package/lib/utils/directive-resolver.d.ts +23 -0
  90. package/lib/utils/directive-resolver.js +50 -0
  91. package/lib/utils/get-attr-specs-spec.d.ts +18 -0
  92. package/lib/utils/get-attr-specs-spec.js +22 -3
  93. package/lib/utils/get-attr-specs.d.ts +9 -0
  94. package/lib/utils/get-attr-specs.js +9 -0
  95. package/lib/utils/get-ns.d.ts +7 -0
  96. package/lib/utils/get-ns.js +7 -0
  97. package/lib/utils/get-spec-by-tag-name.d.ts +12 -1
  98. package/lib/utils/get-spec-by-tag-name.js +11 -0
  99. package/lib/utils/get-spec.d.ts +11 -1
  100. package/lib/utils/get-spec.js +10 -0
  101. package/lib/utils/merge-array.d.ts +10 -0
  102. package/lib/utils/merge-array.js +10 -0
  103. package/lib/utils/resolve-namespace.d.ts +13 -0
  104. package/lib/utils/resolve-namespace.js +10 -0
  105. package/lib/utils/resolve-version.d.ts +11 -0
  106. package/lib/utils/resolve-version.js +11 -0
  107. package/lib/utils/schema-to-spec.d.ts +7 -2
  108. package/lib/utils/schema-to-spec.js +20 -6
  109. package/lib/utils/validate-aria-version.d.ts +7 -0
  110. package/lib/utils/validate-aria-version.js +7 -0
  111. package/package.json +9 -7
@@ -0,0 +1,342 @@
1
+ /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types -- AccnameElement wraps mutable DOM types */
2
+ import { DEFAULT_IMAGE_LABEL, DEFAULT_RESET_LABEL, DEFAULT_SUBMIT_LABEL, TEXT_INPUT_TYPES, } from '../../../const/index.js';
3
+ import { findChildByLocalName, getInputType, isSvgElement, makeResult, resolveNameFromContent } from './helpers.js';
4
+ import { resolveLabelText } from './label-steps.js';
5
+ /**
6
+ * Computes element-specific accessible name per HTML-AAM §4.1.
7
+ *
8
+ * Implements AccName 1.2 §4.3.2 Step 2E: for elements that have a native
9
+ * host language text alternative, use that alternative. The specific rules
10
+ * for each HTML element are defined in HTML-AAM §4.1.
11
+ *
12
+ * Returns null if no element-specific rule applies, letting the caller
13
+ * fall through to name-from-content (Step 2F) or title fallback (Step 2I).
14
+ *
15
+ * Control flow (dispatches by `localName`):
16
+ * - SVG elements → `handleSvgElement` (SVG-AAM: `<title>` child)
17
+ * - `<input>` → `handleInput` (branches by type: text-like, button, image, hidden)
18
+ * - `<textarea>`, `<select>`, `<meter>`, `<progress>`, `<output>` → `handleLabelableWithTitle`
19
+ * - `<button>` → `handleButton` (label → content → title)
20
+ * - `<fieldset>` → `handleFieldset` (legend → title)
21
+ * - `<table>` → `handleTable` (caption → title)
22
+ * - `<img>` → `handleImg` (alt → title)
23
+ * - `<area>` → `handleArea` (alt → title)
24
+ * - `<figure>` → `handleFigure` (title only)
25
+ * - `<summary>` → `handleSummary` (content → title)
26
+ * - `<a href>` → `handleAnchor` (content → title)
27
+ * - `<iframe>` → `handleTitleOnly` (title only)
28
+ * - All others → null (rely on caller's generic Steps 2F/2I)
29
+ *
30
+ * @param el - The element to compute the name for
31
+ * @param resolver - Environment-dependent resolver for DOM traversal and role queries
32
+ * @param visited - Set of element IDs already visited (cycle prevention)
33
+ * @param computeFn - The recursive accessible name computation function
34
+ * @param inLabelledbyTraversal - Whether this computation is part of an aria-labelledby traversal
35
+ * @returns The computed name result, or null if no element-specific rule applies
36
+ * @see https://www.w3.org/TR/accname-1.2/#computation-steps — AccName 1.2 §4.3.2 Step 2E
37
+ * @see https://www.w3.org/TR/html-aam-1.0/#accessible-name-and-description-computation — HTML-AAM §4.1
38
+ */
39
+ export function getElementSpecificName(el, resolver, visited, computeFn, inLabelledbyTraversal) {
40
+ if (isSvgElement(el)) {
41
+ return handleSvgElement(el);
42
+ }
43
+ const { localName } = el;
44
+ switch (localName) {
45
+ case 'input': {
46
+ return handleInput(el, resolver, visited, computeFn, inLabelledbyTraversal);
47
+ }
48
+ case 'textarea':
49
+ case 'select':
50
+ case 'meter':
51
+ case 'progress':
52
+ case 'output': {
53
+ return handleLabelableWithTitle(el, resolver, visited, computeFn, inLabelledbyTraversal);
54
+ }
55
+ case 'button': {
56
+ return handleButton(el, resolver, visited, computeFn, inLabelledbyTraversal);
57
+ }
58
+ case 'fieldset': {
59
+ return handleFieldset(el, resolver, visited, computeFn, inLabelledbyTraversal);
60
+ }
61
+ case 'table': {
62
+ return handleTable(el, resolver, visited, computeFn, inLabelledbyTraversal);
63
+ }
64
+ case 'img': {
65
+ return handleImg(el);
66
+ }
67
+ case 'area': {
68
+ return handleArea(el);
69
+ }
70
+ case 'figure': {
71
+ return handleFigure(el);
72
+ }
73
+ case 'summary': {
74
+ return handleSummary(el, resolver, visited, computeFn, inLabelledbyTraversal);
75
+ }
76
+ case 'a': {
77
+ if (el.hasAttribute('href')) {
78
+ return handleAnchor(el, resolver, visited, computeFn, inLabelledbyTraversal);
79
+ }
80
+ return null;
81
+ }
82
+ case 'iframe': {
83
+ return handleTitleOnly(el);
84
+ }
85
+ default: {
86
+ // All other elements (tr, td, th, section, div, span, p, h1-h6, etc.)
87
+ // only get name from title (handled by caller's title fallback)
88
+ return null;
89
+ }
90
+ }
91
+ }
92
+ /**
93
+ * HTML-AAM §4.1 (input[text-like], textarea, select, meter, progress, output).
94
+ * Name sources: label → title → placeholder.
95
+ * @see https://www.w3.org/TR/html-aam-1.0/#el-input-text
96
+ */
97
+ function handleLabelableWithTitle(el, resolver, visited, computeFn, inLabelledbyTraversal) {
98
+ const labelResult = resolveLabelText(el, resolver, visited, computeFn, inLabelledbyTraversal);
99
+ if (labelResult) {
100
+ return labelResult;
101
+ }
102
+ const title = el.getAttribute('title');
103
+ if (title?.trim()) {
104
+ return makeResult(title, 'title');
105
+ }
106
+ const placeholder = el.getAttribute('placeholder');
107
+ if (placeholder?.trim()) {
108
+ return makeResult(placeholder, 'placeholder');
109
+ }
110
+ return null;
111
+ }
112
+ /**
113
+ * HTML-AAM §4.1 (input — dispatches by type).
114
+ * Text-like types: label → title → placeholder.
115
+ * Button/submit/reset: label → value → default label.
116
+ * Image: label → alt → title → default label.
117
+ * Hidden: always empty.
118
+ * Checkbox/radio: label → title.
119
+ * @see https://www.w3.org/TR/html-aam-1.0/#el-input-text
120
+ */
121
+ function handleInput(el, resolver, visited, computeFn, inLabelledbyTraversal) {
122
+ const type = getInputType(el);
123
+ if (TEXT_INPUT_TYPES.has(type)) {
124
+ return handleLabelableWithTitle(el, resolver, visited, computeFn, inLabelledbyTraversal);
125
+ }
126
+ if (type === 'button' || type === 'submit' || type === 'reset') {
127
+ return handleInputButton(el, type, resolver, visited, computeFn, inLabelledbyTraversal);
128
+ }
129
+ if (type === 'image') {
130
+ return handleInputImage(el, resolver, visited, computeFn, inLabelledbyTraversal);
131
+ }
132
+ if (type === 'hidden') {
133
+ return makeResult('', null);
134
+ }
135
+ // checkbox, radio: label -> title
136
+ return handleLabelableWithTitle(el, resolver, visited, computeFn, inLabelledbyTraversal);
137
+ }
138
+ /**
139
+ * HTML-AAM §4.1 (input[type=button/submit/reset]).
140
+ * Name sources: label → value → title → default label (submit="Submit", reset="Reset").
141
+ * @see https://www.w3.org/TR/html-aam-1.0/#el-input-button
142
+ */
143
+ function handleInputButton(el, type, resolver, visited, computeFn, inLabelledbyTraversal) {
144
+ const labelResult = resolveLabelText(el, resolver, visited, computeFn, inLabelledbyTraversal);
145
+ if (labelResult) {
146
+ return labelResult;
147
+ }
148
+ const value = el.getAttribute('value');
149
+ if (value?.trim()) {
150
+ return makeResult(value, 'value');
151
+ }
152
+ const title = el.getAttribute('title');
153
+ if (title?.trim()) {
154
+ return makeResult(title, 'title');
155
+ }
156
+ // Default label for submit/reset buttons
157
+ if (type === 'submit') {
158
+ return makeResult(DEFAULT_SUBMIT_LABEL, 'default');
159
+ }
160
+ if (type === 'reset') {
161
+ return makeResult(DEFAULT_RESET_LABEL, 'default');
162
+ }
163
+ return null;
164
+ }
165
+ /**
166
+ * HTML-AAM §4.1 (input[type=image]).
167
+ * Name sources: label → alt → title → default ("Submit Query").
168
+ * @see https://www.w3.org/TR/html-aam-1.0/#el-input-image
169
+ */
170
+ function handleInputImage(el, resolver, visited, computeFn, inLabelledbyTraversal) {
171
+ const labelResult = resolveLabelText(el, resolver, visited, computeFn, inLabelledbyTraversal);
172
+ if (labelResult) {
173
+ return labelResult;
174
+ }
175
+ const alt = el.getAttribute('alt');
176
+ if (alt?.trim()) {
177
+ return makeResult(alt, 'alt');
178
+ }
179
+ const title = el.getAttribute('title');
180
+ if (title?.trim()) {
181
+ return makeResult(title, 'title');
182
+ }
183
+ return makeResult(DEFAULT_IMAGE_LABEL, 'default');
184
+ }
185
+ /**
186
+ * HTML-AAM §4.1 (button).
187
+ * Name sources: label → content → title.
188
+ * @see https://www.w3.org/TR/html-aam-1.0/#el-button
189
+ */
190
+ function handleButton(el, resolver, visited, computeFn, inLabelledbyTraversal) {
191
+ const labelResult = resolveLabelText(el, resolver, visited, computeFn, inLabelledbyTraversal);
192
+ if (labelResult) {
193
+ return labelResult;
194
+ }
195
+ const content = resolveNameFromContent(el, resolver, visited, computeFn, inLabelledbyTraversal);
196
+ if (content.trim()) {
197
+ return makeResult(content, 'content');
198
+ }
199
+ const title = el.getAttribute('title');
200
+ if (title?.trim()) {
201
+ return makeResult(title, 'title');
202
+ }
203
+ return null;
204
+ }
205
+ /**
206
+ * HTML-AAM §4.1 (fieldset).
207
+ * Name sources: legend (content) → title.
208
+ * @see https://www.w3.org/TR/html-aam-1.0/#el-fieldset
209
+ */
210
+ function handleFieldset(el, resolver, visited, computeFn, inLabelledbyTraversal) {
211
+ const legend = findChildByLocalName(el, 'legend');
212
+ if (legend) {
213
+ const content = resolveNameFromContent(legend, resolver, visited, computeFn, inLabelledbyTraversal);
214
+ if (content.trim()) {
215
+ return makeResult(content, 'legend');
216
+ }
217
+ }
218
+ const title = el.getAttribute('title');
219
+ if (title?.trim()) {
220
+ return makeResult(title, 'title');
221
+ }
222
+ return null;
223
+ }
224
+ /**
225
+ * HTML-AAM §4.1 (table).
226
+ * Name sources: caption (content) → title.
227
+ * @see https://www.w3.org/TR/html-aam-1.0/#el-table
228
+ */
229
+ function handleTable(el, resolver, visited, computeFn, inLabelledbyTraversal) {
230
+ const caption = findChildByLocalName(el, 'caption');
231
+ if (caption) {
232
+ const content = resolveNameFromContent(caption, resolver, visited, computeFn, inLabelledbyTraversal);
233
+ if (content.trim()) {
234
+ return makeResult(content, 'caption');
235
+ }
236
+ }
237
+ const title = el.getAttribute('title');
238
+ if (title?.trim()) {
239
+ return makeResult(title, 'title');
240
+ }
241
+ return null;
242
+ }
243
+ /**
244
+ * HTML-AAM §4.1 (img).
245
+ * Name sources: alt → title (only when alt is not specified).
246
+ * When alt="" (empty), returns empty name with null source (decorative image).
247
+ * @see https://www.w3.org/TR/html-aam-1.0/#el-img
248
+ */
249
+ function handleImg(el) {
250
+ if (el.hasAttribute('alt')) {
251
+ const alt = el.getAttribute('alt') ?? '';
252
+ return makeResult(alt, alt.trim() ? 'alt' : null);
253
+ }
254
+ const title = el.getAttribute('title');
255
+ if (title?.trim()) {
256
+ return makeResult(title, 'title');
257
+ }
258
+ return null;
259
+ }
260
+ /**
261
+ * HTML-AAM §4.1 (area).
262
+ * Name sources: alt → title.
263
+ * @see https://www.w3.org/TR/html-aam-1.0/#el-area
264
+ */
265
+ function handleArea(el) {
266
+ const alt = el.getAttribute('alt');
267
+ if (alt?.trim()) {
268
+ return makeResult(alt, 'alt');
269
+ }
270
+ const title = el.getAttribute('title');
271
+ if (title?.trim()) {
272
+ return makeResult(title, 'title');
273
+ }
274
+ return null;
275
+ }
276
+ /**
277
+ * HTML-AAM §4.1 (figure).
278
+ * Name sources: title only. Note: figcaption provides the accessible
279
+ * *description*, not the name, per HTML-AAM.
280
+ * @see https://www.w3.org/TR/html-aam-1.0/#el-figure
281
+ */
282
+ function handleFigure(el) {
283
+ const title = el.getAttribute('title');
284
+ if (title?.trim()) {
285
+ return makeResult(title, 'title');
286
+ }
287
+ return null;
288
+ }
289
+ /**
290
+ * HTML-AAM §4.1 (summary).
291
+ * Name sources: content → title.
292
+ * @see https://www.w3.org/TR/html-aam-1.0/#el-summary
293
+ */
294
+ function handleSummary(el, resolver, visited, computeFn, inLabelledbyTraversal) {
295
+ const content = resolveNameFromContent(el, resolver, visited, computeFn, inLabelledbyTraversal);
296
+ if (content.trim()) {
297
+ return makeResult(content, 'content');
298
+ }
299
+ const title = el.getAttribute('title');
300
+ if (title?.trim()) {
301
+ return makeResult(title, 'title');
302
+ }
303
+ return null;
304
+ }
305
+ /**
306
+ * HTML-AAM §4.1 (a[href]).
307
+ * Name sources: content → title.
308
+ * @see https://www.w3.org/TR/html-aam-1.0/#el-a
309
+ */
310
+ function handleAnchor(el, resolver, visited, computeFn, inLabelledbyTraversal) {
311
+ const content = resolveNameFromContent(el, resolver, visited, computeFn, inLabelledbyTraversal);
312
+ if (content.trim()) {
313
+ return makeResult(content, 'content');
314
+ }
315
+ const title = el.getAttribute('title');
316
+ if (title?.trim()) {
317
+ return makeResult(title, 'title');
318
+ }
319
+ return null;
320
+ }
321
+ /**
322
+ * HTML-AAM §4.1 (iframe) — name from title attribute only.
323
+ * @see https://www.w3.org/TR/html-aam-1.0/#el-iframe
324
+ */
325
+ function handleTitleOnly(el) {
326
+ const title = el.getAttribute('title');
327
+ if (title?.trim()) {
328
+ return makeResult(title, 'title');
329
+ }
330
+ return null;
331
+ }
332
+ /**
333
+ * SVG-AAM: SVG elements get name from `<title>` child element.
334
+ * @see https://www.w3.org/TR/svg-aam-1.0/#mapping_additional_nd — SVG-AAM §8.1
335
+ */
336
+ function handleSvgElement(el) {
337
+ const titleEl = findChildByLocalName(el, 'title');
338
+ if (titleEl?.textContent?.trim()) {
339
+ return makeResult(titleEl.textContent, 'svg-title');
340
+ }
341
+ return null;
342
+ }
@@ -0,0 +1,98 @@
1
+ import type { AccnameElement, AccnameResolver, AccnameResult, AccnameSource } from './types.js';
2
+ export { EMBEDDED_CONTROL_ROLES } from '../../../const/index.js';
3
+ /**
4
+ * Creates an AccnameResult with a trimmed, whitespace-collapsed name.
5
+ *
6
+ * @param name - The raw name string to normalize
7
+ * @param source - The source that provided the name, or null if the name is empty
8
+ * @returns A result with the collapsed name and its source (source is null when name is empty)
9
+ */
10
+ export declare function makeResult(name: string, source: AccnameSource | null): AccnameResult;
11
+ /**
12
+ * Collapses internal whitespace and trims a string.
13
+ *
14
+ * @param text - The string to normalize
15
+ * @returns The string with collapsed whitespace and trimmed
16
+ */
17
+ export declare function flattenText(text: string): string;
18
+ /**
19
+ * Collects text content from child nodes recursively for name-from-content computation.
20
+ *
21
+ * Implements AccName 1.2 §4.3.2 Steps 2F and 2C:
22
+ *
23
+ * - **Step 2F**: "If the current node's role allows name from content [...],
24
+ * return the accumulated text of the current node's descendant nodes."
25
+ * - **Step 2C (Embedded Controls)**: "If the current node is a descendant of
26
+ * an `aria-labelledby` or `aria-label` reference AND the current node is
27
+ * an embedded control, return the embedded control's value."
28
+ *
29
+ * Control flow for each child node:
30
+ * 1. **Text node** → contribute text directly.
31
+ * 2. **Embedded control** (textbox, combobox, listbox, slider, spinbutton, searchbox)
32
+ * → use value via `getEmbeddedControlValue`. Per spec, `aria-label` is ignored
33
+ * for embedded controls during name-from-content traversal.
34
+ * 3. **Other element** → first try its full accessible name (Steps 2B–2I via `computeFn`).
35
+ * If no name, fall through to `collectTextContent` for transparent traversal.
36
+ *
37
+ * Parts are joined with a space separator per AccName 1.2 §4.3.2 Step 2C.
38
+ *
39
+ * **Limitation:** CSS-generated content (`::before`/`::after` with the `content`
40
+ * property) is not included. AccName 1.2 §4.3.2 Step 2G specifies that CSS
41
+ * generated textual content should be part of the accumulated text, but markuplint
42
+ * performs static HTML analysis without CSS processing, so this content is
43
+ * unavailable at lint time.
44
+ *
45
+ * @param el - The element whose child nodes to collect text from
46
+ * @param resolver - Environment-dependent resolver for DOM traversal and role queries
47
+ * @param visited - Set of element IDs already visited (cycle prevention)
48
+ * @param computeFn - The recursive accessible name computation function
49
+ * @param inLabelledbyTraversal - Whether this computation is part of an aria-labelledby traversal
50
+ * @returns The concatenated text content from child nodes
51
+ * @see https://www.w3.org/TR/accname-1.2/#computation-steps — AccName 1.2 §4.3.2 Step 2F
52
+ * @see https://www.w3.org/TR/accname-1.2/#comp_embedded_control — AccName 1.2 §4.3.2 Step 2C
53
+ */
54
+ export declare function resolveNameFromContent(el: AccnameElement, resolver: AccnameResolver, visited: ReadonlySet<string>, computeFn: (el: AccnameElement, resolver: AccnameResolver, inLabelledbyTraversal: boolean, visited: ReadonlySet<string>) => AccnameResult, inLabelledbyTraversal: boolean): string;
55
+ /**
56
+ * Finds the first child element with a matching localName.
57
+ *
58
+ * @param el - The parent element to search within
59
+ * @param localName - The local tag name to match
60
+ * @returns The first matching child element, or null if none found
61
+ */
62
+ export declare function findChildByLocalName(el: AccnameElement, localName: string): AccnameElement | null;
63
+ /**
64
+ * Finds the nearest ancestor label element (implicit label association).
65
+ *
66
+ * @param el - The element to search from
67
+ * @returns The nearest ancestor label element, or null if none found
68
+ */
69
+ export declare function findAncestorLabel(el: AccnameElement): AccnameElement | null;
70
+ /**
71
+ * Resolves a label for an element via explicit (for=id) or implicit (ancestor) association.
72
+ *
73
+ * @param el - The element to find labels for
74
+ * @param resolver - Environment-dependent resolver for label lookups
75
+ * @returns An array of label elements associated with the element
76
+ */
77
+ export declare function resolveLabel(el: AccnameElement, resolver: AccnameResolver): readonly AccnameElement[];
78
+ /**
79
+ * Gets the input type, defaulting to 'text' for inputs without a type attribute.
80
+ *
81
+ * @param el - The element to get the input type for
82
+ * @returns The lowercase input type, or an empty string if not an input element
83
+ */
84
+ export declare function getInputType(el: AccnameElement): string;
85
+ /**
86
+ * Checks if an element is in the SVG namespace.
87
+ *
88
+ * @param el - The element to check
89
+ * @returns True if the element is in the SVG namespace
90
+ */
91
+ export declare function isSvgElement(el: AccnameElement): boolean;
92
+ /**
93
+ * Escapes a string for safe use inside a CSS selector.
94
+ *
95
+ * @param value - The raw string value (typically an element ID)
96
+ * @returns The escaped string with CSS special characters backslash-escaped
97
+ */
98
+ export declare function escapeCSS(value: string): string;