@cssdoc/index 0.5.4 → 0.6.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.
- package/dist/index.d.mts +13 -2
- package/dist/index.mjs +58 -3
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -53,7 +53,7 @@ interface CssValueSites {
|
|
|
53
53
|
usages: PropertyUsage[];
|
|
54
54
|
}
|
|
55
55
|
/** The kinds of record member a span can be keyed to. */
|
|
56
|
-
type MemberKind = "record" | "modifier" | "part" | "shadow-part" | "property" | "function" | "animation" | "layer" | "state" | "condition";
|
|
56
|
+
type MemberKind = "record" | "modifier" | "part" | "shadow-part" | "pseudo-element" | "property" | "function" | "animation" | "layer" | "state" | "condition";
|
|
57
57
|
/** Build a stable span key for a member. */
|
|
58
58
|
declare function memberKey(kind: MemberKind, id?: string): string;
|
|
59
59
|
/** One record in the index: its model entry plus source spans and the facts drift checks need. */
|
|
@@ -84,9 +84,20 @@ declare class CssDocIndex {
|
|
|
84
84
|
readonly records: readonly RecordInfo[];
|
|
85
85
|
/** The modifier matcher for this index's convention — how members are matched and rendered. */
|
|
86
86
|
readonly matcher: ModifierMatcher;
|
|
87
|
+
/** Every custom property's effective value (`--x: value` declarations and `@property` initial-values). */
|
|
88
|
+
readonly customPropertyValues: ReadonlyMap<string, string>;
|
|
87
89
|
private readonly byName;
|
|
88
90
|
private readonly byClass;
|
|
89
|
-
constructor(records: RecordInfo[], file?: string, matcher?: ModifierMatcher);
|
|
91
|
+
constructor(records: RecordInfo[], file?: string, matcher?: ModifierMatcher, customPropertyValues?: ReadonlyMap<string, string>);
|
|
92
|
+
/**
|
|
93
|
+
* A custom property's declared value and its fully resolved value — following `var()` references
|
|
94
|
+
* through the index to a terminal literal, the way browser dev tools do. `resolved` is omitted when
|
|
95
|
+
* nothing was followed (no `var()`, or the chain couldn't be resolved further).
|
|
96
|
+
*/
|
|
97
|
+
resolveCustomProperty(name: string): {
|
|
98
|
+
declared?: string;
|
|
99
|
+
resolved?: string;
|
|
100
|
+
};
|
|
90
101
|
/** Every documented record's model entry. */
|
|
91
102
|
get entries(): CssDocEntry[];
|
|
92
103
|
/** The record whose base class matches `className` (with or without a leading dot). */
|
package/dist/index.mjs
CHANGED
|
@@ -34,23 +34,66 @@ const spanOf = (node) => {
|
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* Follow the `var()` references in `value` through `values` to a terminal literal — the resolution a
|
|
39
|
+
* browser's dev tools show. Uses a `var(--x, fallback)` fallback when `--x` is undefined, and leaves a
|
|
40
|
+
* reference in place on an unknown property or a cycle (so the output degrades to the furthest it could
|
|
41
|
+
* reach rather than looping).
|
|
42
|
+
*/
|
|
43
|
+
function resolveValue(value, values, seen) {
|
|
44
|
+
if (!value.includes("var(")) return value;
|
|
45
|
+
const parsed = valueParser(value);
|
|
46
|
+
parsed.walk((node) => {
|
|
47
|
+
if (node.type !== "function" || node.value !== "var") return void 0;
|
|
48
|
+
const ref = node.nodes.find((n) => n.type === "word")?.value;
|
|
49
|
+
if (!ref?.startsWith("--")) return false;
|
|
50
|
+
const comma = node.nodes.findIndex((n) => n.type === "div" && n.value === ",");
|
|
51
|
+
const fallback = comma >= 0 ? valueParser.stringify(node.nodes.slice(comma + 1)).trim() : void 0;
|
|
52
|
+
const declared = seen.has(ref) ? void 0 : values.get(ref);
|
|
53
|
+
const replacement = declared !== void 0 ? resolveValue(declared, values, /* @__PURE__ */ new Set([...seen, ref])) : fallback !== void 0 ? resolveValue(fallback, values, seen) : void 0;
|
|
54
|
+
if (replacement !== void 0) {
|
|
55
|
+
node.type = "word";
|
|
56
|
+
node.value = replacement;
|
|
57
|
+
node.nodes = [];
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
});
|
|
61
|
+
return valueParser.stringify(parsed.nodes);
|
|
62
|
+
}
|
|
37
63
|
/** A queryable view over the parsed records. */
|
|
38
64
|
var CssDocIndex = class {
|
|
39
65
|
file;
|
|
40
66
|
records;
|
|
41
67
|
/** The modifier matcher for this index's convention — how members are matched and rendered. */
|
|
42
68
|
matcher;
|
|
69
|
+
/** Every custom property's effective value (`--x: value` declarations and `@property` initial-values). */
|
|
70
|
+
customPropertyValues;
|
|
43
71
|
byName = /* @__PURE__ */ new Map();
|
|
44
72
|
byClass = /* @__PURE__ */ new Map();
|
|
45
|
-
constructor(records, file, matcher) {
|
|
73
|
+
constructor(records, file, matcher, customPropertyValues = /* @__PURE__ */ new Map()) {
|
|
46
74
|
this.records = records;
|
|
47
75
|
this.file = file;
|
|
48
76
|
this.matcher = matcher ?? new ModifierMatcher(DEFAULT_MODIFIER_CONVENTION);
|
|
77
|
+
this.customPropertyValues = customPropertyValues;
|
|
49
78
|
for (const record of records) {
|
|
50
79
|
this.byName.set(record.entry.name, record);
|
|
51
80
|
this.byClass.set(stripDot(record.entry.className), record);
|
|
52
81
|
}
|
|
53
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* A custom property's declared value and its fully resolved value — following `var()` references
|
|
85
|
+
* through the index to a terminal literal, the way browser dev tools do. `resolved` is omitted when
|
|
86
|
+
* nothing was followed (no `var()`, or the chain couldn't be resolved further).
|
|
87
|
+
*/
|
|
88
|
+
resolveCustomProperty(name) {
|
|
89
|
+
const declared = this.customPropertyValues.get(name);
|
|
90
|
+
if (declared === void 0) return {};
|
|
91
|
+
const resolved = resolveValue(declared, this.customPropertyValues, /* @__PURE__ */ new Set([name]));
|
|
92
|
+
return {
|
|
93
|
+
declared,
|
|
94
|
+
resolved: resolved === declared ? void 0 : resolved
|
|
95
|
+
};
|
|
96
|
+
}
|
|
54
97
|
/** Every documented record's model entry. */
|
|
55
98
|
get entries() {
|
|
56
99
|
return this.records.map((r) => r.entry);
|
|
@@ -159,6 +202,7 @@ function scanNodes(nodes, build, base, matcher) {
|
|
|
159
202
|
for (const s of selector.matchAll(/:state\(\s*([\w-]+)\s*\)/gu)) set(memberKey("state", s[1]), node);
|
|
160
203
|
for (const ps of matcher.pseudoStatesIn(selector)) set(memberKey("state", ps.name), node);
|
|
161
204
|
for (const sp of selector.matchAll(/::part\(\s*([\w-]+)\s*\)/gu)) set(memberKey("shadow-part", sp[1]), node);
|
|
205
|
+
for (const pe of matcher.pseudoElementsIn(selector)) set(memberKey("pseudo-element", pe.name), node);
|
|
162
206
|
const bare = selector.replace(/::?[\w-]+(\([^)]*\))?/gu, "");
|
|
163
207
|
const modNames = /* @__PURE__ */ new Set();
|
|
164
208
|
for (const mod of matcher.modifiersIn(bare, baseNoDot)) {
|
|
@@ -229,14 +273,25 @@ function createIndex(css, options = {}) {
|
|
|
229
273
|
}
|
|
230
274
|
if (current) scanNodes([node], current, current.entry.className, matcher);
|
|
231
275
|
}
|
|
232
|
-
|
|
276
|
+
const records = entries.map((entry) => builds.get(entry.name) ?? {
|
|
233
277
|
entry,
|
|
234
278
|
memberSpans: /* @__PURE__ */ new Map(),
|
|
235
279
|
authoredModifiers: /* @__PURE__ */ new Set(),
|
|
236
280
|
authoredParts: /* @__PURE__ */ new Set(),
|
|
237
281
|
authoredShadowParts: /* @__PURE__ */ new Set(),
|
|
238
282
|
selectorText: ""
|
|
239
|
-
})
|
|
283
|
+
});
|
|
284
|
+
const customPropertyValues = /* @__PURE__ */ new Map();
|
|
285
|
+
root.walkAtRules("property", (at) => {
|
|
286
|
+
const name = at.params.trim();
|
|
287
|
+
at.walkDecls("initial-value", (d) => {
|
|
288
|
+
customPropertyValues.set(name, d.value);
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
root.walkDecls((d) => {
|
|
292
|
+
if (d.prop.startsWith("--")) customPropertyValues.set(d.prop, d.value);
|
|
293
|
+
});
|
|
294
|
+
return new CssDocIndex(records, options.file, matcher, customPropertyValues);
|
|
240
295
|
}
|
|
241
296
|
/**
|
|
242
297
|
* Extract custom-property assignments (`--name: value`) and `var(--name, fallback)` references from
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cssdoc/index",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "A queryable semantic index over the @cssdoc/core model, plus a host-agnostic Usage abstraction and source spans — the shared data layer for cssdoc's linters and language server.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"postcss": "^8.5.19",
|
|
32
32
|
"postcss-value-parser": "^4.2.0",
|
|
33
|
-
"@cssdoc/core": "0.
|
|
33
|
+
"@cssdoc/core": "0.6.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "^24.13.3",
|