@cssdoc/providers 0.3.3 → 0.4.1
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/dist/index.d.mts +36 -4
- package/dist/index.mjs +148 -102
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -71,8 +71,16 @@ type HoverDetail = "compact" | "full" | "custom";
|
|
|
71
71
|
*/
|
|
72
72
|
type HoverSectionMode = "on" | "off" | "auto";
|
|
73
73
|
type HoverSections = Record<string, HoverSectionMode>;
|
|
74
|
-
/** The card's section keys, in render order — the `custom` map is keyed by these. */
|
|
74
|
+
/** The card's section keys, in default render order — the `custom` map is keyed by these. */
|
|
75
75
|
declare const HOVER_SECTION_KEYS: readonly ["summary", "deprecated", "remarks", "accessibility", "modifiers", "parts", "shadowParts", "states", "customProperties", "functions", "slots", "animations", "layers", "conditions", "see", "structure", "examples"];
|
|
76
|
+
/** One hover-card section name. */
|
|
77
|
+
type HoverSectionKey = (typeof HOVER_SECTION_KEYS)[number];
|
|
78
|
+
/**
|
|
79
|
+
* The order sections render in the hover card, and which ones render. Defaults to
|
|
80
|
+
* {@link HOVER_SECTION_KEYS}; supply a subset/reordering to move or drop sections (unlisted sections are
|
|
81
|
+
* omitted). The fixed header (name · kind · release stage · since) always leads.
|
|
82
|
+
*/
|
|
83
|
+
type HoverSectionOrder = readonly HoverSectionKey[];
|
|
76
84
|
/** Options that tune usage checks. */
|
|
77
85
|
interface UsageOptions {
|
|
78
86
|
/**
|
|
@@ -121,12 +129,36 @@ interface SyntaxMatch {
|
|
|
121
129
|
*/
|
|
122
130
|
declare function matchesSyntax(syntax: string, value: string): SyntaxMatch;
|
|
123
131
|
//#endregion
|
|
132
|
+
//#region src/mdn.d.ts
|
|
133
|
+
/**
|
|
134
|
+
* MDN links for CSS value types. A `@property` `syntax` descriptor (e.g. `<color>`, `<length-percentage>`)
|
|
135
|
+
* names value types that MDN documents; this maps each `<type>` to its reference page so hovers and the
|
|
136
|
+
* docs playground can link them. Format-agnostic: {@link linkSyntax} takes a `renderLink` callback so
|
|
137
|
+
* each caller wraps a link in its own output format (a markdown `[…](…)` for hovers, an `<a>` for HTML).
|
|
138
|
+
*
|
|
139
|
+
* @module
|
|
140
|
+
*/
|
|
141
|
+
/** The MDN reference URL for a bare CSS value-type name (e.g. `color`, `length-percentage`). */
|
|
142
|
+
declare function mdnUrlForType(type: string): string;
|
|
143
|
+
/**
|
|
144
|
+
* Rewrite each `<type>` token in a `syntax` descriptor via `renderLink`, leaving the rest untouched.
|
|
145
|
+
* `renderLink` receives the bare type name and its MDN URL and returns the replacement for `<type>`
|
|
146
|
+
* (including the angle brackets). Non-`<type>` text (e.g. `|`, `+`, `#`) passes through verbatim.
|
|
147
|
+
*
|
|
148
|
+
* @param syntax - The `@property` syntax descriptor, e.g. `<color> | <length>`.
|
|
149
|
+
* @param renderLink - Builds the replacement for one `<type>` token.
|
|
150
|
+
* @returns The descriptor with each `<type>` replaced.
|
|
151
|
+
*/
|
|
152
|
+
declare function linkSyntax(syntax: string, renderLink: (type: string, url: string) => string): string;
|
|
153
|
+
//#endregion
|
|
124
154
|
//#region src/directives.d.ts
|
|
125
155
|
type DirectiveKind = "disable" | "enable" | "disable-line" | "disable-next-line" | "expect-error";
|
|
126
156
|
interface Directive {
|
|
127
157
|
kind: DirectiveKind;
|
|
128
158
|
/** Rule ids the directive scopes to, or `null` for every rule. */
|
|
129
159
|
rules: string[] | null;
|
|
160
|
+
/** The author's justification, from a trailing ` - <reason>` on the directive, when present. */
|
|
161
|
+
reason?: string;
|
|
130
162
|
/** 1-based line the comment starts / ends on. */
|
|
131
163
|
startLine: number;
|
|
132
164
|
endLine: number;
|
|
@@ -147,7 +179,7 @@ declare function applyDirectives(diagnostics: Diagnostic[], source: string): Dia
|
|
|
147
179
|
declare const record: {
|
|
148
180
|
model(index: CssDocIndex, naming?: ResolvedNaming, structureIgnore?: readonly string[]): Diagnostic[];
|
|
149
181
|
completions(index: CssDocIndex): Completion[];
|
|
150
|
-
hover(base: string, index: CssDocIndex, detail?: HoverDetail, sections?: HoverSections): Hover | undefined;
|
|
182
|
+
hover(base: string, index: CssDocIndex, detail?: HoverDetail, sections?: HoverSections, sectionOrder?: HoverSectionOrder): Hover | undefined;
|
|
151
183
|
definition(base: string, index: CssDocIndex): Location$1 | undefined;
|
|
152
184
|
};
|
|
153
185
|
declare const modifier: {
|
|
@@ -202,7 +234,7 @@ declare function completeCustomProperties(index: CssDocIndex): Completion[];
|
|
|
202
234
|
/** Completions for a value position: the custom functions. */
|
|
203
235
|
declare function completeFunctions(index: CssDocIndex): Completion[];
|
|
204
236
|
/** Hover for a class token: the modifier's docs, else the component's card (at the given detail). */
|
|
205
|
-
declare function hoverForClass(base: string, token: string, index: CssDocIndex, detail?: HoverDetail, sections?: HoverSections): Hover | undefined;
|
|
237
|
+
declare function hoverForClass(base: string, token: string, index: CssDocIndex, detail?: HoverDetail, sections?: HoverSections, sectionOrder?: HoverSectionOrder): Hover | undefined;
|
|
206
238
|
/** Hover for a `var(--…)` custom property. */
|
|
207
239
|
declare function hoverForCustomProperty(name: string, index: CssDocIndex): Hover | undefined;
|
|
208
240
|
/** Hover for a custom function. */
|
|
@@ -214,4 +246,4 @@ declare function definitionForCustomProperty(name: string, index: CssDocIndex):
|
|
|
214
246
|
/** Definition of a custom function (its `@function` rule). */
|
|
215
247
|
declare function definitionForFunction(name: string, index: CssDocIndex): Location$1 | undefined;
|
|
216
248
|
//#endregion
|
|
217
|
-
export { ASPECTS, Completion, CompletionKind, DEFAULT_RULE_SEVERITIES, Diagnostic, HOVER_SECTION_KEYS, Hover, HoverDetail, HoverSectionMode, HoverSections, type Location, NAME_CASE_PRESETS, NameCase, NamingRules, ResolvedNaming, RuleId, RuleSeverities, RuleSeverity, Severity, type SourceSpan, SyntaxMatch, UsageOptions, applyDirectives, checkClassUsage, checkPropertyAssignments, checkPropertyUsage, completeClasses, completeCustomProperties, completeFunctions, cssPart, customProperty, definitionForClass, definitionForCustomProperty, definitionForFunction, func, hoverForClass, hoverForCustomProperty, hoverForFunction, lintModel, matchesSyntax, modifier, parseDirectives, part, partUsage, record, resolveNaming, resolveRuleSeverities, stateUsage };
|
|
249
|
+
export { ASPECTS, Completion, CompletionKind, DEFAULT_RULE_SEVERITIES, Diagnostic, HOVER_SECTION_KEYS, Hover, HoverDetail, HoverSectionKey, HoverSectionMode, HoverSectionOrder, HoverSections, type Location, NAME_CASE_PRESETS, NameCase, NamingRules, ResolvedNaming, RuleId, RuleSeverities, RuleSeverity, Severity, type SourceSpan, SyntaxMatch, UsageOptions, applyDirectives, checkClassUsage, checkPropertyAssignments, checkPropertyUsage, completeClasses, completeCustomProperties, completeFunctions, cssPart, customProperty, definitionForClass, definitionForCustomProperty, definitionForFunction, func, hoverForClass, hoverForCustomProperty, hoverForFunction, linkSyntax, lintModel, matchesSyntax, mdnUrlForType, modifier, parseDirectives, part, partUsage, record, resolveNaming, resolveRuleSeverities, stateUsage };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
import { memberKey } from "@cssdoc/index";
|
|
2
2
|
import { fork } from "css-tree";
|
|
3
|
+
//#region src/mdn.ts
|
|
4
|
+
/**
|
|
5
|
+
* MDN links for CSS value types. A `@property` `syntax` descriptor (e.g. `<color>`, `<length-percentage>`)
|
|
6
|
+
* names value types that MDN documents; this maps each `<type>` to its reference page so hovers and the
|
|
7
|
+
* docs playground can link them. Format-agnostic: {@link linkSyntax} takes a `renderLink` callback so
|
|
8
|
+
* each caller wraps a link in its own output format (a markdown `[…](…)` for hovers, an `<a>` for HTML).
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
const MDN_URL = { color: "https://developer.mozilla.org/en-US/docs/Web/CSS/color_value" };
|
|
13
|
+
/** The MDN reference URL for a bare CSS value-type name (e.g. `color`, `length-percentage`). */
|
|
14
|
+
function mdnUrlForType(type) {
|
|
15
|
+
return MDN_URL[type] ?? `https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/${type}`;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Rewrite each `<type>` token in a `syntax` descriptor via `renderLink`, leaving the rest untouched.
|
|
19
|
+
* `renderLink` receives the bare type name and its MDN URL and returns the replacement for `<type>`
|
|
20
|
+
* (including the angle brackets). Non-`<type>` text (e.g. `|`, `+`, `#`) passes through verbatim.
|
|
21
|
+
*
|
|
22
|
+
* @param syntax - The `@property` syntax descriptor, e.g. `<color> | <length>`.
|
|
23
|
+
* @param renderLink - Builds the replacement for one `<type>` token.
|
|
24
|
+
* @returns The descriptor with each `<type>` replaced.
|
|
25
|
+
*/
|
|
26
|
+
function linkSyntax(syntax, renderLink) {
|
|
27
|
+
return syntax.replace(/<([a-z][\w-]*)>/gu, (_m, type) => renderLink(type, mdnUrlForType(type)));
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
3
30
|
//#region src/syntax.ts
|
|
4
31
|
/**
|
|
5
32
|
* Match a CSS value against a registered custom property's `@property` `syntax` descriptor, using
|
|
@@ -55,7 +82,96 @@ function matchesSyntax(syntax, value) {
|
|
|
55
82
|
};
|
|
56
83
|
}
|
|
57
84
|
//#endregion
|
|
85
|
+
//#region src/types.ts
|
|
86
|
+
/**
|
|
87
|
+
* The default rule severities. `unknown-modifier` defaults to `warn` — safe under the BEM default's
|
|
88
|
+
* strong `--` signal; lower it to `off` for weak-signal conventions (bare/OOCSS) where every chained
|
|
89
|
+
* class is a candidate. `unknown-custom-property` stays `off` (it needs an opt-in `propertyPrefix`).
|
|
90
|
+
*/
|
|
91
|
+
const DEFAULT_RULE_SEVERITIES = {
|
|
92
|
+
"missing-summary": "warn",
|
|
93
|
+
"undocumented-modifier": "warn",
|
|
94
|
+
"deprecated-requires-canonical": "warn",
|
|
95
|
+
"name-not-in-css": "warn",
|
|
96
|
+
"unknown-modifier": "warn",
|
|
97
|
+
"deprecated-modifier": "warn",
|
|
98
|
+
"unknown-state": "warn",
|
|
99
|
+
"unknown-part": "warn",
|
|
100
|
+
"undocumented-part": "warn",
|
|
101
|
+
"undocumented-css-part": "warn",
|
|
102
|
+
"component-name-case": "warn",
|
|
103
|
+
"part-name-case": "warn",
|
|
104
|
+
"structure-unknown-selector": "warn",
|
|
105
|
+
"invalid-default-value": "warn",
|
|
106
|
+
"invalid-property-value": "warn",
|
|
107
|
+
"invalid-fallback-value": "warn",
|
|
108
|
+
"unknown-custom-property": "off",
|
|
109
|
+
"cssdoc-directive": "warn"
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Merge per-rule overrides over {@link DEFAULT_RULE_SEVERITIES}. A `boolean` override is accepted for
|
|
113
|
+
* back-compat: `false` → `off`, `true` → the rule's default.
|
|
114
|
+
*/
|
|
115
|
+
function resolveRuleSeverities(overrides) {
|
|
116
|
+
const resolved = { ...DEFAULT_RULE_SEVERITIES };
|
|
117
|
+
if (!overrides) return resolved;
|
|
118
|
+
for (const [rule, value] of Object.entries(overrides)) {
|
|
119
|
+
if (value === void 0) continue;
|
|
120
|
+
if (typeof value === "boolean") resolved[rule] = value ? DEFAULT_RULE_SEVERITIES[rule] : "off";
|
|
121
|
+
else resolved[rule] = value;
|
|
122
|
+
}
|
|
123
|
+
return resolved;
|
|
124
|
+
}
|
|
125
|
+
/** The card's section keys, in default render order — the `custom` map is keyed by these. */
|
|
126
|
+
const HOVER_SECTION_KEYS = [
|
|
127
|
+
"summary",
|
|
128
|
+
"deprecated",
|
|
129
|
+
"remarks",
|
|
130
|
+
"accessibility",
|
|
131
|
+
"modifiers",
|
|
132
|
+
"parts",
|
|
133
|
+
"shadowParts",
|
|
134
|
+
"states",
|
|
135
|
+
"customProperties",
|
|
136
|
+
"functions",
|
|
137
|
+
"slots",
|
|
138
|
+
"animations",
|
|
139
|
+
"layers",
|
|
140
|
+
"conditions",
|
|
141
|
+
"see",
|
|
142
|
+
"structure",
|
|
143
|
+
"examples"
|
|
144
|
+
];
|
|
145
|
+
/** The built-in name-case patterns, tested against a class name without its leading dot. */
|
|
146
|
+
const NAME_CASE_PRESETS = {
|
|
147
|
+
pascalCase: /^[A-Z][A-Za-z0-9]*$/u,
|
|
148
|
+
camelCase: /^[a-z][A-Za-z0-9]*$/u,
|
|
149
|
+
lowercase: /^[a-z][a-z0-9-]*$/u
|
|
150
|
+
};
|
|
151
|
+
/** Compile one {@link NameCase} to a regex: a preset, else the string as a custom pattern. */
|
|
152
|
+
function compileNameCase(spec) {
|
|
153
|
+
if (!spec) return void 0;
|
|
154
|
+
if (spec in NAME_CASE_PRESETS) return NAME_CASE_PRESETS[spec];
|
|
155
|
+
try {
|
|
156
|
+
return new RegExp(spec, "u");
|
|
157
|
+
} catch {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/** Compile {@link NamingRules} to regexes once, for the record/part name-case checks. */
|
|
162
|
+
function resolveNaming(naming) {
|
|
163
|
+
return {
|
|
164
|
+
component: compileNameCase(naming?.component),
|
|
165
|
+
part: compileNameCase(naming?.part)
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
//#endregion
|
|
58
169
|
//#region src/aspects.ts
|
|
170
|
+
/** Render a `@property` syntax descriptor with each `<type>` linked to its MDN reference page. */
|
|
171
|
+
const linkedSyntax = (syntax) => {
|
|
172
|
+
const linked = linkSyntax(syntax, (type, url) => `[\`<${type}>\`](${url})`);
|
|
173
|
+
return linked === syntax ? `\`${syntax}\`` : linked;
|
|
174
|
+
};
|
|
59
175
|
const stripDot = (name) => name.replace(/^\./u, "");
|
|
60
176
|
const warn = (d) => ({
|
|
61
177
|
...d,
|
|
@@ -143,7 +259,7 @@ const record = {
|
|
|
143
259
|
deprecated: Boolean(entry.deprecated)
|
|
144
260
|
}));
|
|
145
261
|
},
|
|
146
|
-
hover(base, index, detail = "full", sections) {
|
|
262
|
+
hover(base, index, detail = "full", sections, sectionOrder) {
|
|
147
263
|
const entry = index.componentForClass(base);
|
|
148
264
|
if (!entry) return void 0;
|
|
149
265
|
const selectorFor = (name) => index.matcher.selectorFor(name);
|
|
@@ -175,18 +291,23 @@ const record = {
|
|
|
175
291
|
if (mode === "off") return "skip";
|
|
176
292
|
return has ? "content" : mode === "on" ? "empty" : "skip";
|
|
177
293
|
};
|
|
294
|
+
const fragments = {};
|
|
178
295
|
const prose = (key, prefix, text) => {
|
|
179
296
|
const w = want(key, Boolean(text?.trim()));
|
|
180
|
-
if (w !== "skip")
|
|
297
|
+
if (w !== "skip") fragments[key] = ["", `${prefix}${w === "content" ? text : "_—_"}`];
|
|
181
298
|
};
|
|
182
299
|
const list = (key, icon, label, rows) => {
|
|
183
300
|
const w = want(key, rows.length > 0);
|
|
184
|
-
if (w !== "skip")
|
|
301
|
+
if (w !== "skip") fragments[key] = [
|
|
302
|
+
"",
|
|
303
|
+
`**$(${icon}) ${label}**`,
|
|
304
|
+
...w === "content" ? rows : ["_—_"]
|
|
305
|
+
];
|
|
185
306
|
};
|
|
186
307
|
prose("summary", "", entry.summary);
|
|
187
308
|
{
|
|
188
309
|
const w = want("deprecated", Boolean(entry.deprecated));
|
|
189
|
-
if (w !== "skip")
|
|
310
|
+
if (w !== "skip") fragments.deprecated = ["", w === "content" ? deprecatedLine : `$(warning) ${warnHtml("Deprecated")}`];
|
|
190
311
|
}
|
|
191
312
|
prose("remarks", "", entry.remarks);
|
|
192
313
|
prose("accessibility", "$(accessibility) ", entry.accessibility);
|
|
@@ -202,7 +323,7 @@ const record = {
|
|
|
202
323
|
list("shadowParts", "symbol-namespace", "Shadow parts", entry.shadowParts.map((p) => `- ${styled(`::part(${p.name})`, "field")}${dash(p.description)}`));
|
|
203
324
|
list("states", "symbol-event", "States", entry.states.map((s) => `- ${styled(s.kind === "custom" ? `:state(${s.name})` : `:${s.name}`, "variable")}${dash(s.description)}`));
|
|
204
325
|
list("customProperties", "symbol-variable", "Custom properties", entry.cssPropertiesDeclared.map((p) => {
|
|
205
|
-
const syntax = p.syntax ? `:
|
|
326
|
+
const syntax = p.syntax ? `: ${linkedSyntax(p.syntax)}` : "";
|
|
206
327
|
const def = p.defaultValue ? ` (default \`${p.defaultValue}\`)` : "";
|
|
207
328
|
return `- ${styled(p.name, "variable")}${syntax}${def}${dash(p.description)}`;
|
|
208
329
|
}));
|
|
@@ -215,24 +336,30 @@ const record = {
|
|
|
215
336
|
{
|
|
216
337
|
const w = want("structure", Boolean(entry.structure?.length));
|
|
217
338
|
if (w !== "skip") {
|
|
218
|
-
|
|
339
|
+
const frag = ["", "**$(list-tree) Structure**"];
|
|
219
340
|
if (w === "content") {
|
|
220
|
-
if (entry.structureDescription)
|
|
221
|
-
|
|
222
|
-
} else
|
|
341
|
+
if (entry.structureDescription) frag.push("", entry.structureDescription);
|
|
342
|
+
frag.push("", "```css", ...renderStructureTree(entry.structure ?? []), "```");
|
|
343
|
+
} else frag.push("", "_—_");
|
|
344
|
+
fragments.structure = frag;
|
|
223
345
|
}
|
|
224
346
|
}
|
|
225
347
|
{
|
|
226
348
|
const w = want("examples", entry.examples.length > 0);
|
|
227
349
|
if (w !== "skip") {
|
|
228
|
-
|
|
350
|
+
const frag = ["", `**$(book) Example${entry.examples.length > 1 ? "s" : ""}**`];
|
|
229
351
|
if (w === "content") for (const e of entry.examples) {
|
|
230
352
|
const ex = e.trim();
|
|
231
|
-
|
|
353
|
+
frag.push("", ex.startsWith("```") ? ex : `\`\`\`${ex.includes("<") ? "html" : "css"}\n${ex}\n\`\`\``);
|
|
232
354
|
}
|
|
233
|
-
else
|
|
355
|
+
else frag.push("", "_—_");
|
|
356
|
+
fragments.examples = frag;
|
|
234
357
|
}
|
|
235
358
|
}
|
|
359
|
+
for (const key of sectionOrder ?? HOVER_SECTION_KEYS) {
|
|
360
|
+
const frag = fragments[key];
|
|
361
|
+
if (frag) lines.push(...frag);
|
|
362
|
+
}
|
|
236
363
|
return { contents: lines.join("\n") };
|
|
237
364
|
},
|
|
238
365
|
definition(base, index) {
|
|
@@ -478,7 +605,7 @@ const customProperty = {
|
|
|
478
605
|
const found = findProperty(index, name);
|
|
479
606
|
if (!found) return void 0;
|
|
480
607
|
const p = found.record.entry.cssPropertiesDeclared[found.index];
|
|
481
|
-
const lines = [`\`${p.name}\`${p.syntax ? ` —
|
|
608
|
+
const lines = [`\`${p.name}\`${p.syntax ? ` — ${linkedSyntax(p.syntax)}` : ""}`];
|
|
482
609
|
if (p.defaultValue) lines.push("", `Default: \`${p.defaultValue}\``);
|
|
483
610
|
if (p.description) lines.push("", p.description);
|
|
484
611
|
return { contents: lines.join("\n") };
|
|
@@ -510,90 +637,6 @@ const func = {
|
|
|
510
637
|
}
|
|
511
638
|
};
|
|
512
639
|
//#endregion
|
|
513
|
-
//#region src/types.ts
|
|
514
|
-
/**
|
|
515
|
-
* The default rule severities. `unknown-modifier` defaults to `warn` — safe under the BEM default's
|
|
516
|
-
* strong `--` signal; lower it to `off` for weak-signal conventions (bare/OOCSS) where every chained
|
|
517
|
-
* class is a candidate. `unknown-custom-property` stays `off` (it needs an opt-in `propertyPrefix`).
|
|
518
|
-
*/
|
|
519
|
-
const DEFAULT_RULE_SEVERITIES = {
|
|
520
|
-
"missing-summary": "warn",
|
|
521
|
-
"undocumented-modifier": "warn",
|
|
522
|
-
"deprecated-requires-canonical": "warn",
|
|
523
|
-
"name-not-in-css": "warn",
|
|
524
|
-
"unknown-modifier": "warn",
|
|
525
|
-
"deprecated-modifier": "warn",
|
|
526
|
-
"unknown-state": "warn",
|
|
527
|
-
"unknown-part": "warn",
|
|
528
|
-
"undocumented-part": "warn",
|
|
529
|
-
"undocumented-css-part": "warn",
|
|
530
|
-
"component-name-case": "warn",
|
|
531
|
-
"part-name-case": "warn",
|
|
532
|
-
"structure-unknown-selector": "warn",
|
|
533
|
-
"invalid-default-value": "warn",
|
|
534
|
-
"invalid-property-value": "warn",
|
|
535
|
-
"invalid-fallback-value": "warn",
|
|
536
|
-
"unknown-custom-property": "off",
|
|
537
|
-
"cssdoc-directive": "warn"
|
|
538
|
-
};
|
|
539
|
-
/**
|
|
540
|
-
* Merge per-rule overrides over {@link DEFAULT_RULE_SEVERITIES}. A `boolean` override is accepted for
|
|
541
|
-
* back-compat: `false` → `off`, `true` → the rule's default.
|
|
542
|
-
*/
|
|
543
|
-
function resolveRuleSeverities(overrides) {
|
|
544
|
-
const resolved = { ...DEFAULT_RULE_SEVERITIES };
|
|
545
|
-
if (!overrides) return resolved;
|
|
546
|
-
for (const [rule, value] of Object.entries(overrides)) {
|
|
547
|
-
if (value === void 0) continue;
|
|
548
|
-
if (typeof value === "boolean") resolved[rule] = value ? DEFAULT_RULE_SEVERITIES[rule] : "off";
|
|
549
|
-
else resolved[rule] = value;
|
|
550
|
-
}
|
|
551
|
-
return resolved;
|
|
552
|
-
}
|
|
553
|
-
/** The card's section keys, in render order — the `custom` map is keyed by these. */
|
|
554
|
-
const HOVER_SECTION_KEYS = [
|
|
555
|
-
"summary",
|
|
556
|
-
"deprecated",
|
|
557
|
-
"remarks",
|
|
558
|
-
"accessibility",
|
|
559
|
-
"modifiers",
|
|
560
|
-
"parts",
|
|
561
|
-
"shadowParts",
|
|
562
|
-
"states",
|
|
563
|
-
"customProperties",
|
|
564
|
-
"functions",
|
|
565
|
-
"slots",
|
|
566
|
-
"animations",
|
|
567
|
-
"layers",
|
|
568
|
-
"conditions",
|
|
569
|
-
"see",
|
|
570
|
-
"structure",
|
|
571
|
-
"examples"
|
|
572
|
-
];
|
|
573
|
-
/** The built-in name-case patterns, tested against a class name without its leading dot. */
|
|
574
|
-
const NAME_CASE_PRESETS = {
|
|
575
|
-
pascalCase: /^[A-Z][A-Za-z0-9]*$/u,
|
|
576
|
-
camelCase: /^[a-z][A-Za-z0-9]*$/u,
|
|
577
|
-
lowercase: /^[a-z][a-z0-9-]*$/u
|
|
578
|
-
};
|
|
579
|
-
/** Compile one {@link NameCase} to a regex: a preset, else the string as a custom pattern. */
|
|
580
|
-
function compileNameCase(spec) {
|
|
581
|
-
if (!spec) return void 0;
|
|
582
|
-
if (spec in NAME_CASE_PRESETS) return NAME_CASE_PRESETS[spec];
|
|
583
|
-
try {
|
|
584
|
-
return new RegExp(spec, "u");
|
|
585
|
-
} catch {
|
|
586
|
-
return;
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
/** Compile {@link NamingRules} to regexes once, for the record/part name-case checks. */
|
|
590
|
-
function resolveNaming(naming) {
|
|
591
|
-
return {
|
|
592
|
-
component: compileNameCase(naming?.component),
|
|
593
|
-
part: compileNameCase(naming?.part)
|
|
594
|
-
};
|
|
595
|
-
}
|
|
596
|
-
//#endregion
|
|
597
640
|
//#region src/directives.ts
|
|
598
641
|
const DIRECTIVE_RE = /\/\*\s*cssdoc-(disable-next-line|disable-line|disable|enable|expect-error)\b([^*]*?)\*\//gu;
|
|
599
642
|
const lineAt = (source, index) => {
|
|
@@ -606,10 +649,13 @@ function parseDirectives(source) {
|
|
|
606
649
|
const out = [];
|
|
607
650
|
for (const m of source.matchAll(DIRECTIVE_RE)) {
|
|
608
651
|
const at = m.index ?? 0;
|
|
609
|
-
const
|
|
652
|
+
const reasonAt = m[2].search(/\s-\s/u);
|
|
653
|
+
const rulesPart = (reasonAt === -1 ? m[2] : m[2].slice(0, reasonAt)).trim();
|
|
654
|
+
const reason = reasonAt === -1 ? void 0 : m[2].slice(reasonAt).replace(/^\s-\s/u, "").trim();
|
|
610
655
|
out.push({
|
|
611
656
|
kind: m[1],
|
|
612
|
-
rules:
|
|
657
|
+
rules: rulesPart ? rulesPart.split(/[\s,]+/u).filter(Boolean) : null,
|
|
658
|
+
reason: reason || void 0,
|
|
613
659
|
startLine: lineAt(source, at),
|
|
614
660
|
endLine: lineAt(source, at + m[0].length - 1)
|
|
615
661
|
});
|
|
@@ -758,8 +804,8 @@ function completeFunctions(index) {
|
|
|
758
804
|
return func.completions(index);
|
|
759
805
|
}
|
|
760
806
|
/** Hover for a class token: the modifier's docs, else the component's card (at the given detail). */
|
|
761
|
-
function hoverForClass(base, token, index, detail = "full", sections) {
|
|
762
|
-
return modifier.hover(base, token, index) ?? record.hover(base, index, detail, sections);
|
|
807
|
+
function hoverForClass(base, token, index, detail = "full", sections, sectionOrder) {
|
|
808
|
+
return modifier.hover(base, token, index) ?? record.hover(base, index, detail, sections, sectionOrder);
|
|
763
809
|
}
|
|
764
810
|
/** Hover for a `var(--…)` custom property. */
|
|
765
811
|
function hoverForCustomProperty(name, index) {
|
|
@@ -782,4 +828,4 @@ function definitionForFunction(name, index) {
|
|
|
782
828
|
return func.definition(name, index);
|
|
783
829
|
}
|
|
784
830
|
//#endregion
|
|
785
|
-
export { ASPECTS, DEFAULT_RULE_SEVERITIES, HOVER_SECTION_KEYS, NAME_CASE_PRESETS, applyDirectives, checkClassUsage, checkPropertyAssignments, checkPropertyUsage, completeClasses, completeCustomProperties, completeFunctions, cssPart, customProperty, definitionForClass, definitionForCustomProperty, definitionForFunction, func, hoverForClass, hoverForCustomProperty, hoverForFunction, lintModel, matchesSyntax, modifier, parseDirectives, part, partUsage, record, resolveNaming, resolveRuleSeverities, stateUsage };
|
|
831
|
+
export { ASPECTS, DEFAULT_RULE_SEVERITIES, HOVER_SECTION_KEYS, NAME_CASE_PRESETS, applyDirectives, checkClassUsage, checkPropertyAssignments, checkPropertyUsage, completeClasses, completeCustomProperties, completeFunctions, cssPart, customProperty, definitionForClass, definitionForCustomProperty, definitionForFunction, func, hoverForClass, hoverForCustomProperty, hoverForFunction, linkSyntax, lintModel, matchesSyntax, mdnUrlForType, modifier, parseDirectives, part, partUsage, record, resolveNaming, resolveRuleSeverities, stateUsage };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cssdoc/providers",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Host-agnostic aspect providers over the @cssdoc/index — diagnostics, completions, hover, and definitions for modifiers, custom properties, structure, functions, states, and conditions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"css-tree": "^3.2.1",
|
|
32
|
-
"@cssdoc/core": "0.
|
|
33
|
-
"@cssdoc/index": "0.
|
|
32
|
+
"@cssdoc/core": "0.4.1",
|
|
33
|
+
"@cssdoc/index": "0.4.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/css-tree": "^2.3.11",
|