@navecss/core 0.4.0 → 0.5.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/CONSUMER-ATOMS.md +15 -11
- package/LICENSE +22 -0
- package/README.md +265 -27
- package/dist/{atom-names-2OreuBx9.d.ts → atom-names-B8Ud-7zD.d.ts} +2 -1
- package/dist/atoms.d.ts +3 -2
- package/dist/bin.js +98 -15
- package/dist/check.d.ts +2 -1
- package/dist/check.js +4 -3
- package/dist/{chunk-NFS2REPQ.js → chunk-2K5EBBF2.js} +1 -191
- package/dist/chunk-2TNTYI4L.js +7 -0
- package/dist/{chunk-LQSGQ2OA.js → chunk-63H2FLGU.js} +3 -2
- package/dist/{chunk-E5F6YF7A.js → chunk-BCUK4M4P.js} +346 -9
- package/dist/{chunk-XQQCDUV6.js → chunk-CTFEYJBE.js} +1 -1
- package/dist/{chunk-2A7IUZBH.js → chunk-KKUYU75D.js} +8 -8
- package/dist/chunk-MWHZ26S4.js +4059 -0
- package/dist/chunk-UVHGEVMV.js +204 -0
- package/dist/{chunk-UANF3FGO.js → chunk-ZNTNLGEC.js} +2 -1
- package/dist/collect.d.ts +43 -5
- package/dist/collect.js +2 -1
- package/dist/css.d.ts +1 -0
- package/dist/cx.d.ts +1 -1
- package/dist/lightningcss.d.ts +3 -2
- package/dist/lightningcss.js +7 -4
- package/dist/postcss.d.ts +29 -3
- package/dist/postcss.js +331 -81
- package/dist/standalone.css +2 -0
- package/dist/{vite-options-D1-hGA9L.d.ts → vite-options-sOCeGn9B.d.ts} +3 -2
- package/dist/vite.d.ts +24 -3
- package/dist/vite.js +1077 -1015
- package/package.json +54 -24
- package/skills/navecss/SKILL.md +14 -0
- package/dist/chunk-LADFXRWQ.js +0 -1089
|
@@ -0,0 +1,4059 @@
|
|
|
1
|
+
import { positionWarnings, reportDiagnostics, matchBrackets, createPositionFinder, isNaveAtKeyword, readItem, atKeywordName, OPENERS } from './chunk-UVHGEVMV.js';
|
|
2
|
+
import { decodeIncomingMap, MappingsBuilder } from './chunk-SYNQJNVB.js';
|
|
3
|
+
import { atoms } from './chunk-CUL5PLPI.js';
|
|
4
|
+
import { tokenize } from './chunk-2K5EBBF2.js';
|
|
5
|
+
|
|
6
|
+
// src/directive/expand-text-output.ts
|
|
7
|
+
function toOriginal(position, incoming) {
|
|
8
|
+
if (!incoming) return position;
|
|
9
|
+
const original = incoming.originalPositionFor(position);
|
|
10
|
+
return original ? { line: original.line, column: original.column, sourceIndex: original.sourceIndex } : void 0;
|
|
11
|
+
}
|
|
12
|
+
function appendMappedRange(ctx, range, sourceForToken) {
|
|
13
|
+
const { builder, output, incoming } = ctx;
|
|
14
|
+
const { text, rangeStart, rangeEnd, tokensInRange } = range;
|
|
15
|
+
let cursor = rangeStart;
|
|
16
|
+
for (const token of tokensInRange) {
|
|
17
|
+
const before = text.slice(cursor, token.startIndex);
|
|
18
|
+
output.push(before);
|
|
19
|
+
builder.advance(before);
|
|
20
|
+
const source = toOriginal(sourceForToken(token), incoming);
|
|
21
|
+
if (source) builder.mark(source);
|
|
22
|
+
const end = Math.min(token.endIndex, rangeEnd);
|
|
23
|
+
const body = text.slice(token.startIndex, end);
|
|
24
|
+
output.push(body);
|
|
25
|
+
builder.advance(body);
|
|
26
|
+
cursor = end;
|
|
27
|
+
}
|
|
28
|
+
const rest = text.slice(cursor, rangeEnd);
|
|
29
|
+
output.push(rest);
|
|
30
|
+
builder.advance(rest);
|
|
31
|
+
}
|
|
32
|
+
function tokensBetween(tokens, cursor, start, end) {
|
|
33
|
+
let i = cursor.index;
|
|
34
|
+
while (i < tokens.length && tokens[i].startIndex < start) i++;
|
|
35
|
+
const result = [];
|
|
36
|
+
while (i < tokens.length && tokens[i].startIndex < end) {
|
|
37
|
+
result.push(tokens[i]);
|
|
38
|
+
i++;
|
|
39
|
+
}
|
|
40
|
+
cursor.index = i;
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
function appendGap(ctx, gap) {
|
|
44
|
+
appendMappedRange(
|
|
45
|
+
ctx,
|
|
46
|
+
{
|
|
47
|
+
text: gap.css,
|
|
48
|
+
rangeStart: gap.start,
|
|
49
|
+
rangeEnd: gap.end,
|
|
50
|
+
tokensInRange: tokensBetween(gap.tokens, ctx.gapTokenCursor, gap.start, gap.end)
|
|
51
|
+
},
|
|
52
|
+
(t) => gap.positionAt(t.startIndex)
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
function appendEditParts(ctx, edit) {
|
|
56
|
+
for (const part of edit.parts) {
|
|
57
|
+
const partTokens = tokenize(part.text);
|
|
58
|
+
appendMappedRange(
|
|
59
|
+
ctx,
|
|
60
|
+
{ text: part.text, rangeStart: 0, rangeEnd: part.text.length, tokensInRange: partTokens },
|
|
61
|
+
() => part.source
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function buildOutput(input) {
|
|
66
|
+
const incoming = input.inputSourceMap ? decodeIncomingMap(input.inputSourceMap) : void 0;
|
|
67
|
+
const sorted = [...input.edits].toSorted((a, b) => a.start - b.start || a.end - b.end);
|
|
68
|
+
const ctx = {
|
|
69
|
+
builder: new MappingsBuilder(),
|
|
70
|
+
output: [],
|
|
71
|
+
incoming,
|
|
72
|
+
gapTokenCursor: { index: 0 }
|
|
73
|
+
};
|
|
74
|
+
let cursor = 0;
|
|
75
|
+
for (const edit of sorted) {
|
|
76
|
+
appendGap(ctx, {
|
|
77
|
+
css: input.css,
|
|
78
|
+
tokens: input.tokens,
|
|
79
|
+
start: cursor,
|
|
80
|
+
end: edit.start,
|
|
81
|
+
positionAt: input.positionAt
|
|
82
|
+
});
|
|
83
|
+
appendEditParts(ctx, edit);
|
|
84
|
+
cursor = Math.max(cursor, edit.end);
|
|
85
|
+
}
|
|
86
|
+
appendGap(ctx, {
|
|
87
|
+
css: input.css,
|
|
88
|
+
tokens: input.tokens,
|
|
89
|
+
start: cursor,
|
|
90
|
+
end: input.css.length,
|
|
91
|
+
positionAt: input.positionAt
|
|
92
|
+
});
|
|
93
|
+
const sources = incoming ? [...incoming.sources] : [input.from ?? "<input>"];
|
|
94
|
+
const map = {
|
|
95
|
+
version: 3,
|
|
96
|
+
sources,
|
|
97
|
+
names: [],
|
|
98
|
+
mappings: ctx.builder.toMappings(),
|
|
99
|
+
// Kept as authored, not re-derived: the incoming map's own sourceRoot
|
|
100
|
+
// and sourcesContent describe ITS sources, unrelated to anything this
|
|
101
|
+
// pass computes, and dropping them silently would strand a devtools
|
|
102
|
+
// "view source" that only ever worked because they were there.
|
|
103
|
+
...incoming?.sourceRoot !== void 0 && { sourceRoot: incoming.sourceRoot },
|
|
104
|
+
...incoming?.sourcesContent !== void 0 && { sourcesContent: incoming.sourcesContent }
|
|
105
|
+
};
|
|
106
|
+
return { css: ctx.output.join(""), map: JSON.stringify(map) };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// src/directive/expand-text-render.ts
|
|
110
|
+
function withoutLineTerminators(value) {
|
|
111
|
+
return value.replaceAll(/\r\n|[\r\n\f]/g, " ");
|
|
112
|
+
}
|
|
113
|
+
function renderDeclarations(decls) {
|
|
114
|
+
return decls.map((d) => `${d.prop}: ${withoutLineTerminators(d.value)}`).join("; ");
|
|
115
|
+
}
|
|
116
|
+
function renderRule(selector, decls) {
|
|
117
|
+
return `${selector} { ${renderDeclarations(decls)} }`;
|
|
118
|
+
}
|
|
119
|
+
function renderBlock(block) {
|
|
120
|
+
if (block.kind === "pseudo") return renderRule(block.selector, block.declarations);
|
|
121
|
+
const inner = [];
|
|
122
|
+
if (block.declarations.length > 0) inner.push(renderRule("&", block.declarations));
|
|
123
|
+
for (const pseudo of block.pseudos) inner.push(renderRule(pseudo.selector, pseudo.declarations));
|
|
124
|
+
return `@${block.kind} ${block.condition} { ${inner.join(" ")} }`;
|
|
125
|
+
}
|
|
126
|
+
function renderEmissions(emissions) {
|
|
127
|
+
return emissions.map((emission) => {
|
|
128
|
+
if (emission.kind === "block") return renderBlock(emission.block);
|
|
129
|
+
if (emission.isWrapped) return renderRule("&", emission.declarations);
|
|
130
|
+
return `${renderDeclarations(emission.declarations)};`;
|
|
131
|
+
}).join(" ");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// src/directive/condition-overlap.ts
|
|
135
|
+
var LENGTH = String.raw`[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?[a-z]+`;
|
|
136
|
+
var OPERATOR = "(<=|>=|<|>|=)";
|
|
137
|
+
var AXIS = "(width|height)";
|
|
138
|
+
var RANGE_FEATURE = new RegExp(
|
|
139
|
+
String.raw`^(?:(${LENGTH})\s*${OPERATOR}\s*)?${AXIS}(?:\s*${OPERATOR}\s*(${LENGTH}))?$`
|
|
140
|
+
);
|
|
141
|
+
var LEGACY_FEATURE = new RegExp(String.raw`^(min-|max-)?${AXIS}\s*:\s*(${LENGTH})$`);
|
|
142
|
+
var FEATURE_GROUP = /\(([^()]*)\)/g;
|
|
143
|
+
var FEATURE_CHAIN = /^G(?:\s+and\s+G)*$/;
|
|
144
|
+
var FLIPPED = { "<": ">", "<=": ">=", "=": "=", ">": "<", ">=": "<=" };
|
|
145
|
+
var LEGACY_OPERATORS = { "max-": "<=", "min-": ">=" };
|
|
146
|
+
var LENGTH_PARTS = /^([+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?)([a-z]+)$/;
|
|
147
|
+
function boundsOf(axis, operator, length) {
|
|
148
|
+
const parts = LENGTH_PARTS.exec(length);
|
|
149
|
+
if (!parts) return void 0;
|
|
150
|
+
const value = Number(parts[1]);
|
|
151
|
+
const unit = parts[2];
|
|
152
|
+
const isStrict = operator === "<" || operator === ">";
|
|
153
|
+
const lower = { axis, side: "lower", value, unit, isStrict };
|
|
154
|
+
const upper = { axis, side: "upper", value, unit, isStrict };
|
|
155
|
+
if (operator === "=") return [lower, upper];
|
|
156
|
+
return operator === ">" || operator === ">=" ? [lower] : [upper];
|
|
157
|
+
}
|
|
158
|
+
function legacyBounds(content) {
|
|
159
|
+
const match = LEGACY_FEATURE.exec(content);
|
|
160
|
+
if (!match) return void 0;
|
|
161
|
+
return boundsOf(match[2], LEGACY_OPERATORS[match[1] ?? ""] ?? "=", match[3]);
|
|
162
|
+
}
|
|
163
|
+
function isUp(operator) {
|
|
164
|
+
return operator === "<" || operator === "<=";
|
|
165
|
+
}
|
|
166
|
+
function isDown(operator) {
|
|
167
|
+
return operator === ">" || operator === ">=";
|
|
168
|
+
}
|
|
169
|
+
function isLegalRelation(left, right) {
|
|
170
|
+
if (!left && !right) return false;
|
|
171
|
+
if (!left || !right) return true;
|
|
172
|
+
return isUp(left) && isUp(right) || isDown(left) && isDown(right);
|
|
173
|
+
}
|
|
174
|
+
function rangeBounds(content) {
|
|
175
|
+
const match = RANGE_FEATURE.exec(content);
|
|
176
|
+
if (!match) return void 0;
|
|
177
|
+
const [, leftLength, leftOperator, axis, rightOperator, rightLength] = match;
|
|
178
|
+
if (!isLegalRelation(leftOperator, rightOperator)) return void 0;
|
|
179
|
+
const left = leftOperator ? boundsOf(axis, FLIPPED[leftOperator], leftLength) : [];
|
|
180
|
+
const right = rightOperator ? boundsOf(axis, rightOperator, rightLength) : [];
|
|
181
|
+
return left && right ? [...left, ...right] : void 0;
|
|
182
|
+
}
|
|
183
|
+
function featureBounds(content) {
|
|
184
|
+
const text = content.trim();
|
|
185
|
+
return text.includes(":") ? legacyBounds(text) : rangeBounds(text);
|
|
186
|
+
}
|
|
187
|
+
function mediaBounds(prelude) {
|
|
188
|
+
const text = prelude.replaceAll(/\/\*[\s\S]*?\*\//g, " ").toLowerCase().trim();
|
|
189
|
+
const contents = text.matchAll(FEATURE_GROUP).map((match) => match[1]).toArray();
|
|
190
|
+
if (!FEATURE_CHAIN.test(text.replaceAll(FEATURE_GROUP, "G"))) return void 0;
|
|
191
|
+
const bounds = [];
|
|
192
|
+
for (const content of contents) {
|
|
193
|
+
const found = featureBounds(content);
|
|
194
|
+
if (!found) return void 0;
|
|
195
|
+
bounds.push(...found);
|
|
196
|
+
}
|
|
197
|
+
return bounds;
|
|
198
|
+
}
|
|
199
|
+
var BOUNDS_OF = /* @__PURE__ */ new WeakMap();
|
|
200
|
+
function collectBounds(rules) {
|
|
201
|
+
const known = BOUNDS_OF.get(rules);
|
|
202
|
+
if (known !== void 0) return known;
|
|
203
|
+
const bounds = rules.flatMap(
|
|
204
|
+
(rule) => rule.name === "media" ? mediaBounds(rule.prelude) ?? [] : []
|
|
205
|
+
);
|
|
206
|
+
BOUNDS_OF.set(rules, bounds);
|
|
207
|
+
return bounds;
|
|
208
|
+
}
|
|
209
|
+
function isTighter(candidate, current) {
|
|
210
|
+
if (!current) return true;
|
|
211
|
+
if (candidate.value === current.value) return candidate.isStrict && !current.isStrict;
|
|
212
|
+
return candidate.side === "lower" ? candidate.value > current.value : candidate.value < current.value;
|
|
213
|
+
}
|
|
214
|
+
function tightest(bounds) {
|
|
215
|
+
let lower;
|
|
216
|
+
let upper;
|
|
217
|
+
for (const bound of bounds) {
|
|
218
|
+
if (bound.side === "lower" && isTighter(bound, lower)) lower = bound;
|
|
219
|
+
if (bound.side === "upper" && isTighter(bound, upper)) upper = bound;
|
|
220
|
+
}
|
|
221
|
+
return { lower, upper };
|
|
222
|
+
}
|
|
223
|
+
function isEmptyAxis(bounds) {
|
|
224
|
+
if (new Set(bounds.map((bound) => bound.unit)).size > 1) return false;
|
|
225
|
+
const { lower, upper } = tightest(bounds);
|
|
226
|
+
if (!lower || !upper) return false;
|
|
227
|
+
if (lower.value !== upper.value) return lower.value > upper.value;
|
|
228
|
+
return lower.isStrict || upper.isStrict;
|
|
229
|
+
}
|
|
230
|
+
function conditionsMayOverlap(a, b) {
|
|
231
|
+
const bounds = [...collectBounds(a), ...collectBounds(b)];
|
|
232
|
+
const axes = ["width", "height"];
|
|
233
|
+
return axes.every((axis) => !isEmptyAxis(bounds.filter((bound) => bound.axis === axis)));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// src/directive/property-table.generated.ts
|
|
237
|
+
var PROPERTY_LONGHANDS = {
|
|
238
|
+
"accent-color": ["accent-color"],
|
|
239
|
+
"align-content": ["align-content"],
|
|
240
|
+
"align-items": ["align-items"],
|
|
241
|
+
"align-self": ["align-self"],
|
|
242
|
+
"align-tracks": ["align-tracks"],
|
|
243
|
+
"alignment-baseline": ["alignment-baseline"],
|
|
244
|
+
"all": ["accent-color", "align-content", "align-items", "align-self", "align-tracks", "alignment-baseline", "anchor-name", "anchor-scope", "animation-composition", "animation-delay", "animation-direction", "animation-duration", "animation-fill-mode", "animation-iteration-count", "animation-name", "animation-play-state", "animation-range-end", "animation-range-start", "animation-timeline", "animation-timing-function", "animation-trigger", "appearance", "aspect-ratio", "backdrop-filter", "backface-visibility", "background-attachment", "background-blend-mode", "background-clip", "background-color", "background-image", "background-origin", "background-position-x", "background-position-y", "background-repeat", "background-size", "baseline-shift", "baseline-source", "block-size", "border-block-end-color", "border-block-end-style", "border-block-end-width", "border-block-start-color", "border-block-start-style", "border-block-start-width", "border-bottom-color", "border-bottom-left-radius", "border-bottom-right-radius", "border-bottom-style", "border-bottom-width", "border-collapse", "border-end-end-radius", "border-end-start-radius", "border-image-outset", "border-image-repeat", "border-image-slice", "border-image-source", "border-image-width", "border-inline-end-color", "border-inline-end-style", "border-inline-end-width", "border-inline-start-color", "border-inline-start-style", "border-inline-start-width", "border-left-color", "border-left-style", "border-left-width", "border-right-color", "border-right-style", "border-right-width", "border-shape", "border-spacing", "border-start-end-radius", "border-start-start-radius", "border-top-color", "border-top-left-radius", "border-top-right-radius", "border-top-style", "border-top-width", "bottom", "box-align", "box-decoration-break", "box-direction", "box-flex", "box-flex-group", "box-lines", "box-ordinal-group", "box-orient", "box-pack", "box-shadow", "box-sizing", "break-after", "break-before", "break-inside", "caption-side", "caret-animation", "caret-color", "caret-shape", "clear", "clip", "clip-path", "clip-rule", "color", "color-interpolation-filters", "color-scheme", "column-count", "column-fill", "column-gap", "column-height", "column-rule-color", "column-rule-style", "column-rule-width", "column-span", "column-width", "column-wrap", "contain", "contain-intrinsic-block-size", "contain-intrinsic-height", "contain-intrinsic-inline-size", "contain-intrinsic-width", "container-name", "container-type", "content", "content-visibility", "corner-bottom-left-shape", "corner-bottom-right-shape", "corner-end-end-shape", "corner-end-start-shape", "corner-start-end-shape", "corner-start-start-shape", "corner-top-left-shape", "corner-top-right-shape", "counter-increment", "counter-reset", "counter-set", "cursor", "cx", "cy", "d", "display", "dominant-baseline", "dynamic-range-limit", "empty-cells", "field-sizing", "fill", "fill-opacity", "fill-rule", "filter", "flex-basis", "flex-direction", "flex-grow", "flex-line-count", "flex-shrink", "flex-wrap", "float", "flood-color", "flood-opacity", "font-family", "font-feature-settings", "font-kerning", "font-language-override", "font-optical-sizing", "font-palette", "font-size", "font-size-adjust", "font-smooth", "font-stretch", "font-style", "font-synthesis-position", "font-synthesis-small-caps", "font-synthesis-style", "font-synthesis-weight", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-emoji", "font-variant-ligatures", "font-variant-numeric", "font-variant-position", "font-variation-settings", "font-weight", "font-width", "forced-color-adjust", "frame-sizing", "grid-auto-columns", "grid-auto-flow", "grid-auto-rows", "grid-column-end", "grid-column-gap", "grid-column-start", "grid-row-end", "grid-row-gap", "grid-row-start", "grid-template-areas", "grid-template-columns", "grid-template-rows", "hanging-punctuation", "height", "hyphenate-character", "hyphenate-limit-chars", "hyphens", "image-orientation", "image-rendering", "image-resolution", "ime-mode", "initial-letter", "initial-letter-align", "inline-size", "inset-block-end", "inset-block-start", "inset-inline-end", "inset-inline-start", "interactivity", "interest-delay-end", "interest-delay-start", "interpolate-size", "isolation", "justify-content", "justify-items", "justify-self", "justify-tracks", "left", "letter-spacing", "lighting-color", "line-break", "line-clamp", "line-height", "line-height-step", "link-parameters", "list-style-image", "list-style-position", "list-style-type", "margin-block-end", "margin-block-start", "margin-bottom", "margin-inline-end", "margin-inline-start", "margin-left", "margin-right", "margin-top", "margin-trim", "marker", "marker-end", "marker-mid", "marker-start", "mask-border-mode", "mask-border-outset", "mask-border-repeat", "mask-border-slice", "mask-border-source", "mask-border-width", "mask-clip", "mask-composite", "mask-image", "mask-mode", "mask-origin", "mask-position", "mask-repeat", "mask-size", "mask-type", "masonry-auto-flow", "math-depth", "math-shift", "math-style", "max-block-size", "max-height", "max-inline-size", "max-lines", "max-width", "min-block-size", "min-height", "min-inline-size", "min-width", "mix-blend-mode", "object-fit", "object-position", "object-view-box", "offset-anchor", "offset-distance", "offset-path", "offset-position", "offset-rotate", "opacity", "order", "orphans", "outline-color", "outline-offset", "outline-style", "outline-width", "overflow-anchor", "overflow-block", "overflow-clip-box", "overflow-clip-margin", "overflow-inline", "overflow-wrap", "overflow-x", "overflow-y", "overlay", "overscroll-behavior-block", "overscroll-behavior-inline", "overscroll-behavior-x", "overscroll-behavior-y", "padding-block-end", "padding-block-start", "padding-bottom", "padding-inline-end", "padding-inline-start", "padding-left", "padding-right", "padding-top", "page", "paint-order", "path-length", "perspective", "perspective-origin", "pointer-events", "position", "position-anchor", "position-area", "position-try-fallbacks", "position-try-order", "position-visibility", "print-color-adjust", "quotes", "r", "reading-flow", "reading-order", "resize", "right", "rotate", "row-gap", "ruby-align", "ruby-merge", "ruby-overhang", "ruby-position", "rx", "ry", "scale", "scroll-axis-lock", "scroll-behavior", "scroll-initial-target", "scroll-margin-block-end", "scroll-margin-block-start", "scroll-margin-bottom", "scroll-margin-inline-end", "scroll-margin-inline-start", "scroll-margin-left", "scroll-margin-right", "scroll-margin-top", "scroll-marker-group", "scroll-padding-block-end", "scroll-padding-block-start", "scroll-padding-bottom", "scroll-padding-inline-end", "scroll-padding-inline-start", "scroll-padding-left", "scroll-padding-right", "scroll-padding-top", "scroll-snap-align", "scroll-snap-coordinate", "scroll-snap-destination", "scroll-snap-points-x", "scroll-snap-points-y", "scroll-snap-stop", "scroll-snap-type", "scroll-snap-type-x", "scroll-snap-type-y", "scroll-target-group", "scroll-timeline-axis", "scroll-timeline-name", "scrollbar-color", "scrollbar-gutter", "scrollbar-width", "shape-image-threshold", "shape-margin", "shape-outside", "shape-rendering", "speak-as", "stop-color", "stop-opacity", "stroke", "stroke-color", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "tab-size", "table-layout", "text-align", "text-align-last", "text-anchor", "text-autospace", "text-box", "text-box-edge", "text-box-trim", "text-combine-upright", "text-decoration-color", "text-decoration-inset", "text-decoration-line", "text-decoration-skip", "text-decoration-skip-ink", "text-decoration-style", "text-decoration-thickness", "text-emphasis-color", "text-emphasis-position", "text-emphasis-style", "text-fit", "text-indent", "text-justify", "text-orientation", "text-overflow", "text-rendering", "text-shadow", "text-size-adjust", "text-spacing-trim", "text-transform", "text-underline-offset", "text-underline-position", "text-wrap-mode", "text-wrap-style", "timeline-scope", "timeline-trigger-activation-range-end", "timeline-trigger-activation-range-start", "timeline-trigger-active-range-end", "timeline-trigger-active-range-start", "timeline-trigger-name", "timeline-trigger-source", "top", "touch-action", "transform", "transform-box", "transform-origin", "transform-style", "transition-behavior", "transition-delay", "transition-duration", "transition-property", "transition-timing-function", "translate", "trigger-scope", "user-select", "vector-effect", "vertical-align", "view-timeline-axis", "view-timeline-inset", "view-timeline-name", "view-transition-class", "view-transition-name", "view-transition-scope", "visibility", "white-space-collapse", "white-space-trim", "widows", "width", "will-change", "window-drag", "word-break", "word-spacing", "word-wrap", "writing-mode", "x", "y", "z-index", "zoom"],
|
|
245
|
+
"anchor-name": ["anchor-name"],
|
|
246
|
+
"anchor-scope": ["anchor-scope"],
|
|
247
|
+
"animation": ["animation-delay", "animation-direction", "animation-duration", "animation-fill-mode", "animation-iteration-count", "animation-name", "animation-play-state", "animation-timeline", "animation-timing-function"],
|
|
248
|
+
"animation-composition": ["animation-composition"],
|
|
249
|
+
"animation-delay": ["animation-delay"],
|
|
250
|
+
"animation-direction": ["animation-direction"],
|
|
251
|
+
"animation-duration": ["animation-duration"],
|
|
252
|
+
"animation-fill-mode": ["animation-fill-mode"],
|
|
253
|
+
"animation-iteration-count": ["animation-iteration-count"],
|
|
254
|
+
"animation-name": ["animation-name"],
|
|
255
|
+
"animation-play-state": ["animation-play-state"],
|
|
256
|
+
"animation-range": ["animation-range-end", "animation-range-start"],
|
|
257
|
+
"animation-range-end": ["animation-range-end"],
|
|
258
|
+
"animation-range-start": ["animation-range-start"],
|
|
259
|
+
"animation-timeline": ["animation-timeline"],
|
|
260
|
+
"animation-timing-function": ["animation-timing-function"],
|
|
261
|
+
"animation-trigger": ["animation-trigger"],
|
|
262
|
+
"appearance": ["appearance"],
|
|
263
|
+
"aspect-ratio": ["aspect-ratio"],
|
|
264
|
+
"backdrop-filter": ["backdrop-filter"],
|
|
265
|
+
"backface-visibility": ["backface-visibility"],
|
|
266
|
+
"background": ["background-attachment", "background-clip", "background-color", "background-image", "background-origin", "background-position-x", "background-position-y", "background-repeat", "background-size"],
|
|
267
|
+
"background-attachment": ["background-attachment"],
|
|
268
|
+
"background-blend-mode": ["background-blend-mode"],
|
|
269
|
+
"background-clip": ["background-clip"],
|
|
270
|
+
"background-color": ["background-color"],
|
|
271
|
+
"background-image": ["background-image"],
|
|
272
|
+
"background-origin": ["background-origin"],
|
|
273
|
+
"background-position": ["background-position-x", "background-position-y"],
|
|
274
|
+
"background-position-x": ["background-position-x"],
|
|
275
|
+
"background-position-y": ["background-position-y"],
|
|
276
|
+
"background-repeat": ["background-repeat"],
|
|
277
|
+
"background-size": ["background-size"],
|
|
278
|
+
"baseline-shift": ["baseline-shift"],
|
|
279
|
+
"baseline-source": ["baseline-source"],
|
|
280
|
+
"block-size": ["block-size"],
|
|
281
|
+
"border": ["border-bottom-color", "border-bottom-style", "border-bottom-width", "border-image-outset", "border-image-repeat", "border-image-slice", "border-image-source", "border-image-width", "border-left-color", "border-left-style", "border-left-width", "border-right-color", "border-right-style", "border-right-width", "border-top-color", "border-top-style", "border-top-width"],
|
|
282
|
+
"border-block": ["border-block-end-color", "border-block-end-style", "border-block-end-width", "border-block-start-color", "border-block-start-style", "border-block-start-width"],
|
|
283
|
+
"border-block-color": ["border-block-end-color", "border-block-start-color"],
|
|
284
|
+
"border-block-end": ["border-block-end-color", "border-block-end-style", "border-block-end-width"],
|
|
285
|
+
"border-block-end-color": ["border-block-end-color"],
|
|
286
|
+
"border-block-end-style": ["border-block-end-style"],
|
|
287
|
+
"border-block-end-width": ["border-block-end-width"],
|
|
288
|
+
"border-block-start": ["border-block-start-color", "border-block-start-style", "border-block-start-width"],
|
|
289
|
+
"border-block-start-color": ["border-block-start-color"],
|
|
290
|
+
"border-block-start-style": ["border-block-start-style"],
|
|
291
|
+
"border-block-start-width": ["border-block-start-width"],
|
|
292
|
+
"border-block-style": ["border-block-end-style", "border-block-start-style"],
|
|
293
|
+
"border-block-width": ["border-block-end-width", "border-block-start-width"],
|
|
294
|
+
"border-bottom": ["border-bottom-color", "border-bottom-style", "border-bottom-width"],
|
|
295
|
+
"border-bottom-color": ["border-bottom-color"],
|
|
296
|
+
"border-bottom-left-radius": ["border-bottom-left-radius"],
|
|
297
|
+
"border-bottom-right-radius": ["border-bottom-right-radius"],
|
|
298
|
+
"border-bottom-style": ["border-bottom-style"],
|
|
299
|
+
"border-bottom-width": ["border-bottom-width"],
|
|
300
|
+
"border-collapse": ["border-collapse"],
|
|
301
|
+
"border-color": ["border-bottom-color", "border-left-color", "border-right-color", "border-top-color"],
|
|
302
|
+
"border-end-end-radius": ["border-end-end-radius"],
|
|
303
|
+
"border-end-start-radius": ["border-end-start-radius"],
|
|
304
|
+
"border-image": ["border-image-outset", "border-image-repeat", "border-image-slice", "border-image-source", "border-image-width"],
|
|
305
|
+
"border-image-outset": ["border-image-outset"],
|
|
306
|
+
"border-image-repeat": ["border-image-repeat"],
|
|
307
|
+
"border-image-slice": ["border-image-slice"],
|
|
308
|
+
"border-image-source": ["border-image-source"],
|
|
309
|
+
"border-image-width": ["border-image-width"],
|
|
310
|
+
"border-inline": ["border-inline-end-color", "border-inline-end-style", "border-inline-end-width", "border-inline-start-color", "border-inline-start-style", "border-inline-start-width"],
|
|
311
|
+
"border-inline-color": ["border-inline-end-color", "border-inline-start-color"],
|
|
312
|
+
"border-inline-end": ["border-inline-end-color", "border-inline-end-style", "border-inline-end-width"],
|
|
313
|
+
"border-inline-end-color": ["border-inline-end-color"],
|
|
314
|
+
"border-inline-end-style": ["border-inline-end-style"],
|
|
315
|
+
"border-inline-end-width": ["border-inline-end-width"],
|
|
316
|
+
"border-inline-start": ["border-inline-start-color", "border-inline-start-style", "border-inline-start-width"],
|
|
317
|
+
"border-inline-start-color": ["border-inline-start-color"],
|
|
318
|
+
"border-inline-start-style": ["border-inline-start-style"],
|
|
319
|
+
"border-inline-start-width": ["border-inline-start-width"],
|
|
320
|
+
"border-inline-style": ["border-inline-end-style", "border-inline-start-style"],
|
|
321
|
+
"border-inline-width": ["border-inline-end-width", "border-inline-start-width"],
|
|
322
|
+
"border-left": ["border-left-color", "border-left-style", "border-left-width"],
|
|
323
|
+
"border-left-color": ["border-left-color"],
|
|
324
|
+
"border-left-style": ["border-left-style"],
|
|
325
|
+
"border-left-width": ["border-left-width"],
|
|
326
|
+
"border-radius": ["border-bottom-left-radius", "border-bottom-right-radius", "border-top-left-radius", "border-top-right-radius"],
|
|
327
|
+
"border-right": ["border-right-color", "border-right-style", "border-right-width"],
|
|
328
|
+
"border-right-color": ["border-right-color"],
|
|
329
|
+
"border-right-style": ["border-right-style"],
|
|
330
|
+
"border-right-width": ["border-right-width"],
|
|
331
|
+
"border-shape": ["border-shape"],
|
|
332
|
+
"border-spacing": ["border-spacing"],
|
|
333
|
+
"border-start-end-radius": ["border-start-end-radius"],
|
|
334
|
+
"border-start-start-radius": ["border-start-start-radius"],
|
|
335
|
+
"border-style": ["border-bottom-style", "border-left-style", "border-right-style", "border-top-style"],
|
|
336
|
+
"border-top": ["border-top-color", "border-top-style", "border-top-width"],
|
|
337
|
+
"border-top-color": ["border-top-color"],
|
|
338
|
+
"border-top-left-radius": ["border-top-left-radius"],
|
|
339
|
+
"border-top-right-radius": ["border-top-right-radius"],
|
|
340
|
+
"border-top-style": ["border-top-style"],
|
|
341
|
+
"border-top-width": ["border-top-width"],
|
|
342
|
+
"border-width": ["border-bottom-width", "border-left-width", "border-right-width", "border-top-width"],
|
|
343
|
+
"bottom": ["bottom"],
|
|
344
|
+
"box-align": ["box-align"],
|
|
345
|
+
"box-decoration-break": ["box-decoration-break"],
|
|
346
|
+
"box-direction": ["box-direction"],
|
|
347
|
+
"box-flex": ["box-flex"],
|
|
348
|
+
"box-flex-group": ["box-flex-group"],
|
|
349
|
+
"box-lines": ["box-lines"],
|
|
350
|
+
"box-ordinal-group": ["box-ordinal-group"],
|
|
351
|
+
"box-orient": ["box-orient"],
|
|
352
|
+
"box-pack": ["box-pack"],
|
|
353
|
+
"box-shadow": ["box-shadow"],
|
|
354
|
+
"box-sizing": ["box-sizing"],
|
|
355
|
+
"break-after": ["break-after"],
|
|
356
|
+
"break-before": ["break-before"],
|
|
357
|
+
"break-inside": ["break-inside"],
|
|
358
|
+
"caption-side": ["caption-side"],
|
|
359
|
+
"caret": ["caret-animation", "caret-color", "caret-shape"],
|
|
360
|
+
"caret-animation": ["caret-animation"],
|
|
361
|
+
"caret-color": ["caret-color"],
|
|
362
|
+
"caret-shape": ["caret-shape"],
|
|
363
|
+
"clear": ["clear"],
|
|
364
|
+
"clip": ["clip"],
|
|
365
|
+
"clip-path": ["clip-path"],
|
|
366
|
+
"clip-rule": ["clip-rule"],
|
|
367
|
+
"color": ["color"],
|
|
368
|
+
"color-interpolation-filters": ["color-interpolation-filters"],
|
|
369
|
+
"color-scheme": ["color-scheme"],
|
|
370
|
+
"column-count": ["column-count"],
|
|
371
|
+
"column-fill": ["column-fill"],
|
|
372
|
+
"column-gap": ["column-gap"],
|
|
373
|
+
"column-height": ["column-height"],
|
|
374
|
+
"column-rule": ["column-rule-color", "column-rule-style", "column-rule-width"],
|
|
375
|
+
"column-rule-color": ["column-rule-color"],
|
|
376
|
+
"column-rule-style": ["column-rule-style"],
|
|
377
|
+
"column-rule-width": ["column-rule-width"],
|
|
378
|
+
"column-span": ["column-span"],
|
|
379
|
+
"column-width": ["column-width"],
|
|
380
|
+
"column-wrap": ["column-wrap"],
|
|
381
|
+
"columns": ["column-count", "column-height", "column-width"],
|
|
382
|
+
"contain": ["contain"],
|
|
383
|
+
"contain-intrinsic-block-size": ["contain-intrinsic-block-size"],
|
|
384
|
+
"contain-intrinsic-height": ["contain-intrinsic-height"],
|
|
385
|
+
"contain-intrinsic-inline-size": ["contain-intrinsic-inline-size"],
|
|
386
|
+
"contain-intrinsic-size": ["contain-intrinsic-height", "contain-intrinsic-width"],
|
|
387
|
+
"contain-intrinsic-width": ["contain-intrinsic-width"],
|
|
388
|
+
"container": ["container-name", "container-type"],
|
|
389
|
+
"container-name": ["container-name"],
|
|
390
|
+
"container-type": ["container-type"],
|
|
391
|
+
"content": ["content"],
|
|
392
|
+
"content-visibility": ["content-visibility"],
|
|
393
|
+
"corner-block-end-shape": ["corner-end-end-shape", "corner-end-start-shape"],
|
|
394
|
+
"corner-block-start-shape": ["corner-start-end-shape", "corner-start-start-shape"],
|
|
395
|
+
"corner-bottom-left-shape": ["corner-bottom-left-shape"],
|
|
396
|
+
"corner-bottom-right-shape": ["corner-bottom-right-shape"],
|
|
397
|
+
"corner-bottom-shape": ["corner-bottom-left-shape", "corner-bottom-right-shape"],
|
|
398
|
+
"corner-end-end-shape": ["corner-end-end-shape"],
|
|
399
|
+
"corner-end-start-shape": ["corner-end-start-shape"],
|
|
400
|
+
"corner-inline-end-shape": ["corner-end-end-shape", "corner-start-end-shape"],
|
|
401
|
+
"corner-inline-start-shape": ["corner-start-end-shape", "corner-start-start-shape"],
|
|
402
|
+
"corner-left-shape": ["corner-bottom-left-shape", "corner-top-left-shape"],
|
|
403
|
+
"corner-right-shape": ["corner-bottom-right-shape", "corner-top-right-shape"],
|
|
404
|
+
"corner-shape": ["corner-bottom-left-shape", "corner-bottom-right-shape", "corner-top-left-shape", "corner-top-right-shape"],
|
|
405
|
+
"corner-start-end-shape": ["corner-start-end-shape"],
|
|
406
|
+
"corner-start-start-shape": ["corner-start-start-shape"],
|
|
407
|
+
"corner-top-left-shape": ["corner-top-left-shape"],
|
|
408
|
+
"corner-top-right-shape": ["corner-top-right-shape"],
|
|
409
|
+
"corner-top-shape": ["corner-top-left-shape", "corner-top-right-shape"],
|
|
410
|
+
"counter-increment": ["counter-increment"],
|
|
411
|
+
"counter-reset": ["counter-reset"],
|
|
412
|
+
"counter-set": ["counter-set"],
|
|
413
|
+
"cursor": ["cursor"],
|
|
414
|
+
"cx": ["cx"],
|
|
415
|
+
"cy": ["cy"],
|
|
416
|
+
"d": ["d"],
|
|
417
|
+
"direction": ["direction"],
|
|
418
|
+
"display": ["display"],
|
|
419
|
+
"dominant-baseline": ["dominant-baseline"],
|
|
420
|
+
"dynamic-range-limit": ["dynamic-range-limit"],
|
|
421
|
+
"empty-cells": ["empty-cells"],
|
|
422
|
+
"field-sizing": ["field-sizing"],
|
|
423
|
+
"fill": ["fill"],
|
|
424
|
+
"fill-opacity": ["fill-opacity"],
|
|
425
|
+
"fill-rule": ["fill-rule"],
|
|
426
|
+
"filter": ["filter"],
|
|
427
|
+
"flex": ["flex-basis", "flex-grow", "flex-shrink"],
|
|
428
|
+
"flex-basis": ["flex-basis"],
|
|
429
|
+
"flex-direction": ["flex-direction"],
|
|
430
|
+
"flex-flow": ["flex-direction", "flex-wrap"],
|
|
431
|
+
"flex-grow": ["flex-grow"],
|
|
432
|
+
"flex-line-count": ["flex-line-count"],
|
|
433
|
+
"flex-shrink": ["flex-shrink"],
|
|
434
|
+
"flex-wrap": ["flex-wrap"],
|
|
435
|
+
"float": ["float"],
|
|
436
|
+
"flood-color": ["flood-color"],
|
|
437
|
+
"flood-opacity": ["flood-opacity"],
|
|
438
|
+
"font": ["font-family", "font-feature-settings", "font-kerning", "font-language-override", "font-optical-sizing", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-emoji", "font-variant-ligatures", "font-variant-numeric", "font-variant-position", "font-variation-settings", "font-weight", "font-width", "line-height"],
|
|
439
|
+
"font-family": ["font-family"],
|
|
440
|
+
"font-feature-settings": ["font-feature-settings"],
|
|
441
|
+
"font-kerning": ["font-kerning"],
|
|
442
|
+
"font-language-override": ["font-language-override"],
|
|
443
|
+
"font-optical-sizing": ["font-optical-sizing"],
|
|
444
|
+
"font-palette": ["font-palette"],
|
|
445
|
+
"font-size": ["font-size"],
|
|
446
|
+
"font-size-adjust": ["font-size-adjust"],
|
|
447
|
+
"font-smooth": ["font-smooth"],
|
|
448
|
+
"font-stretch": ["font-stretch"],
|
|
449
|
+
"font-style": ["font-style"],
|
|
450
|
+
"font-synthesis": ["font-synthesis-position", "font-synthesis-small-caps", "font-synthesis-style", "font-synthesis-weight"],
|
|
451
|
+
"font-synthesis-position": ["font-synthesis-position"],
|
|
452
|
+
"font-synthesis-small-caps": ["font-synthesis-small-caps"],
|
|
453
|
+
"font-synthesis-style": ["font-synthesis-style"],
|
|
454
|
+
"font-synthesis-weight": ["font-synthesis-weight"],
|
|
455
|
+
"font-variant": ["font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-emoji", "font-variant-ligatures", "font-variant-numeric", "font-variant-position"],
|
|
456
|
+
"font-variant-alternates": ["font-variant-alternates"],
|
|
457
|
+
"font-variant-caps": ["font-variant-caps"],
|
|
458
|
+
"font-variant-east-asian": ["font-variant-east-asian"],
|
|
459
|
+
"font-variant-emoji": ["font-variant-emoji"],
|
|
460
|
+
"font-variant-ligatures": ["font-variant-ligatures"],
|
|
461
|
+
"font-variant-numeric": ["font-variant-numeric"],
|
|
462
|
+
"font-variant-position": ["font-variant-position"],
|
|
463
|
+
"font-variation-settings": ["font-variation-settings"],
|
|
464
|
+
"font-weight": ["font-weight"],
|
|
465
|
+
"font-width": ["font-width"],
|
|
466
|
+
"forced-color-adjust": ["forced-color-adjust"],
|
|
467
|
+
"frame-sizing": ["frame-sizing"],
|
|
468
|
+
"gap": ["column-gap", "row-gap"],
|
|
469
|
+
"grid": ["column-gap", "grid-auto-columns", "grid-auto-flow", "grid-auto-rows", "grid-column-gap", "grid-row-gap", "grid-template-areas", "grid-template-columns", "grid-template-rows", "row-gap"],
|
|
470
|
+
"grid-area": ["grid-column-end", "grid-column-start", "grid-row-end", "grid-row-start"],
|
|
471
|
+
"grid-auto-columns": ["grid-auto-columns"],
|
|
472
|
+
"grid-auto-flow": ["grid-auto-flow"],
|
|
473
|
+
"grid-auto-rows": ["grid-auto-rows"],
|
|
474
|
+
"grid-column": ["grid-column-end", "grid-column-start"],
|
|
475
|
+
"grid-column-end": ["grid-column-end"],
|
|
476
|
+
"grid-column-gap": ["grid-column-gap"],
|
|
477
|
+
"grid-column-start": ["grid-column-start"],
|
|
478
|
+
"grid-gap": ["grid-column-gap", "grid-row-gap"],
|
|
479
|
+
"grid-row": ["grid-row-end", "grid-row-start"],
|
|
480
|
+
"grid-row-end": ["grid-row-end"],
|
|
481
|
+
"grid-row-gap": ["grid-row-gap"],
|
|
482
|
+
"grid-row-start": ["grid-row-start"],
|
|
483
|
+
"grid-template": ["grid-template-areas", "grid-template-columns", "grid-template-rows"],
|
|
484
|
+
"grid-template-areas": ["grid-template-areas"],
|
|
485
|
+
"grid-template-columns": ["grid-template-columns"],
|
|
486
|
+
"grid-template-rows": ["grid-template-rows"],
|
|
487
|
+
"hanging-punctuation": ["hanging-punctuation"],
|
|
488
|
+
"height": ["height"],
|
|
489
|
+
"hyphenate-character": ["hyphenate-character"],
|
|
490
|
+
"hyphenate-limit-chars": ["hyphenate-limit-chars"],
|
|
491
|
+
"hyphens": ["hyphens"],
|
|
492
|
+
"image-orientation": ["image-orientation"],
|
|
493
|
+
"image-rendering": ["image-rendering"],
|
|
494
|
+
"image-resolution": ["image-resolution"],
|
|
495
|
+
"ime-mode": ["ime-mode"],
|
|
496
|
+
"initial-letter": ["initial-letter"],
|
|
497
|
+
"initial-letter-align": ["initial-letter-align"],
|
|
498
|
+
"inline-size": ["inline-size"],
|
|
499
|
+
"inset": ["bottom", "left", "right", "top"],
|
|
500
|
+
"inset-block": ["inset-block-end", "inset-block-start"],
|
|
501
|
+
"inset-block-end": ["inset-block-end"],
|
|
502
|
+
"inset-block-start": ["inset-block-start"],
|
|
503
|
+
"inset-inline": ["inset-inline-end", "inset-inline-start"],
|
|
504
|
+
"inset-inline-end": ["inset-inline-end"],
|
|
505
|
+
"inset-inline-start": ["inset-inline-start"],
|
|
506
|
+
"interactivity": ["interactivity"],
|
|
507
|
+
"interest-delay": ["interest-delay-end", "interest-delay-start"],
|
|
508
|
+
"interest-delay-end": ["interest-delay-end"],
|
|
509
|
+
"interest-delay-start": ["interest-delay-start"],
|
|
510
|
+
"interpolate-size": ["interpolate-size"],
|
|
511
|
+
"isolation": ["isolation"],
|
|
512
|
+
"justify-content": ["justify-content"],
|
|
513
|
+
"justify-items": ["justify-items"],
|
|
514
|
+
"justify-self": ["justify-self"],
|
|
515
|
+
"justify-tracks": ["justify-tracks"],
|
|
516
|
+
"left": ["left"],
|
|
517
|
+
"letter-spacing": ["letter-spacing"],
|
|
518
|
+
"lighting-color": ["lighting-color"],
|
|
519
|
+
"line-break": ["line-break"],
|
|
520
|
+
"line-clamp": ["line-clamp"],
|
|
521
|
+
"line-height": ["line-height"],
|
|
522
|
+
"line-height-step": ["line-height-step"],
|
|
523
|
+
"link-parameters": ["link-parameters"],
|
|
524
|
+
"list-style": ["list-style-image", "list-style-position", "list-style-type"],
|
|
525
|
+
"list-style-image": ["list-style-image"],
|
|
526
|
+
"list-style-position": ["list-style-position"],
|
|
527
|
+
"list-style-type": ["list-style-type"],
|
|
528
|
+
"margin": ["margin-bottom", "margin-left", "margin-right", "margin-top"],
|
|
529
|
+
"margin-block": ["margin-block-end", "margin-block-start"],
|
|
530
|
+
"margin-block-end": ["margin-block-end"],
|
|
531
|
+
"margin-block-start": ["margin-block-start"],
|
|
532
|
+
"margin-bottom": ["margin-bottom"],
|
|
533
|
+
"margin-inline": ["margin-inline-end", "margin-inline-start"],
|
|
534
|
+
"margin-inline-end": ["margin-inline-end"],
|
|
535
|
+
"margin-inline-start": ["margin-inline-start"],
|
|
536
|
+
"margin-left": ["margin-left"],
|
|
537
|
+
"margin-right": ["margin-right"],
|
|
538
|
+
"margin-top": ["margin-top"],
|
|
539
|
+
"margin-trim": ["margin-trim"],
|
|
540
|
+
"marker": ["marker"],
|
|
541
|
+
"marker-end": ["marker-end"],
|
|
542
|
+
"marker-mid": ["marker-mid"],
|
|
543
|
+
"marker-start": ["marker-start"],
|
|
544
|
+
"mask": ["mask-clip", "mask-composite", "mask-image", "mask-mode", "mask-origin", "mask-position", "mask-repeat", "mask-size"],
|
|
545
|
+
"mask-border": ["mask-border-mode", "mask-border-outset", "mask-border-repeat", "mask-border-slice", "mask-border-source", "mask-border-width"],
|
|
546
|
+
"mask-border-mode": ["mask-border-mode"],
|
|
547
|
+
"mask-border-outset": ["mask-border-outset"],
|
|
548
|
+
"mask-border-repeat": ["mask-border-repeat"],
|
|
549
|
+
"mask-border-slice": ["mask-border-slice"],
|
|
550
|
+
"mask-border-source": ["mask-border-source"],
|
|
551
|
+
"mask-border-width": ["mask-border-width"],
|
|
552
|
+
"mask-clip": ["mask-clip"],
|
|
553
|
+
"mask-composite": ["mask-composite"],
|
|
554
|
+
"mask-image": ["mask-image"],
|
|
555
|
+
"mask-mode": ["mask-mode"],
|
|
556
|
+
"mask-origin": ["mask-origin"],
|
|
557
|
+
"mask-position": ["mask-position"],
|
|
558
|
+
"mask-repeat": ["mask-repeat"],
|
|
559
|
+
"mask-size": ["mask-size"],
|
|
560
|
+
"mask-type": ["mask-type"],
|
|
561
|
+
"masonry-auto-flow": ["masonry-auto-flow"],
|
|
562
|
+
"math-depth": ["math-depth"],
|
|
563
|
+
"math-shift": ["math-shift"],
|
|
564
|
+
"math-style": ["math-style"],
|
|
565
|
+
"max-block-size": ["max-block-size"],
|
|
566
|
+
"max-height": ["max-height"],
|
|
567
|
+
"max-inline-size": ["max-inline-size"],
|
|
568
|
+
"max-lines": ["max-lines"],
|
|
569
|
+
"max-width": ["max-width"],
|
|
570
|
+
"min-block-size": ["min-block-size"],
|
|
571
|
+
"min-height": ["min-height"],
|
|
572
|
+
"min-inline-size": ["min-inline-size"],
|
|
573
|
+
"min-width": ["min-width"],
|
|
574
|
+
"mix-blend-mode": ["mix-blend-mode"],
|
|
575
|
+
"object-fit": ["object-fit"],
|
|
576
|
+
"object-position": ["object-position"],
|
|
577
|
+
"object-view-box": ["object-view-box"],
|
|
578
|
+
"offset": ["offset-anchor", "offset-distance", "offset-path", "offset-position", "offset-rotate"],
|
|
579
|
+
"offset-anchor": ["offset-anchor"],
|
|
580
|
+
"offset-distance": ["offset-distance"],
|
|
581
|
+
"offset-path": ["offset-path"],
|
|
582
|
+
"offset-position": ["offset-position"],
|
|
583
|
+
"offset-rotate": ["offset-rotate"],
|
|
584
|
+
"opacity": ["opacity"],
|
|
585
|
+
"order": ["order"],
|
|
586
|
+
"orphans": ["orphans"],
|
|
587
|
+
"outline": ["outline-color", "outline-style", "outline-width"],
|
|
588
|
+
"outline-color": ["outline-color"],
|
|
589
|
+
"outline-offset": ["outline-offset"],
|
|
590
|
+
"outline-style": ["outline-style"],
|
|
591
|
+
"outline-width": ["outline-width"],
|
|
592
|
+
"overflow": ["overflow-x", "overflow-y"],
|
|
593
|
+
"overflow-anchor": ["overflow-anchor"],
|
|
594
|
+
"overflow-block": ["overflow-block"],
|
|
595
|
+
"overflow-clip-box": ["overflow-clip-box"],
|
|
596
|
+
"overflow-clip-margin": ["overflow-clip-margin"],
|
|
597
|
+
"overflow-inline": ["overflow-inline"],
|
|
598
|
+
"overflow-wrap": ["overflow-wrap"],
|
|
599
|
+
"overflow-x": ["overflow-x"],
|
|
600
|
+
"overflow-y": ["overflow-y"],
|
|
601
|
+
"overlay": ["overlay"],
|
|
602
|
+
"overscroll-behavior": ["overscroll-behavior-x", "overscroll-behavior-y"],
|
|
603
|
+
"overscroll-behavior-block": ["overscroll-behavior-block"],
|
|
604
|
+
"overscroll-behavior-inline": ["overscroll-behavior-inline"],
|
|
605
|
+
"overscroll-behavior-x": ["overscroll-behavior-x"],
|
|
606
|
+
"overscroll-behavior-y": ["overscroll-behavior-y"],
|
|
607
|
+
"padding": ["padding-bottom", "padding-left", "padding-right", "padding-top"],
|
|
608
|
+
"padding-block": ["padding-block-end", "padding-block-start"],
|
|
609
|
+
"padding-block-end": ["padding-block-end"],
|
|
610
|
+
"padding-block-start": ["padding-block-start"],
|
|
611
|
+
"padding-bottom": ["padding-bottom"],
|
|
612
|
+
"padding-inline": ["padding-inline-end", "padding-inline-start"],
|
|
613
|
+
"padding-inline-end": ["padding-inline-end"],
|
|
614
|
+
"padding-inline-start": ["padding-inline-start"],
|
|
615
|
+
"padding-left": ["padding-left"],
|
|
616
|
+
"padding-right": ["padding-right"],
|
|
617
|
+
"padding-top": ["padding-top"],
|
|
618
|
+
"page": ["page"],
|
|
619
|
+
"page-break-after": ["break-after"],
|
|
620
|
+
"page-break-before": ["break-before"],
|
|
621
|
+
"page-break-inside": ["break-inside"],
|
|
622
|
+
"paint-order": ["paint-order"],
|
|
623
|
+
"path-length": ["path-length"],
|
|
624
|
+
"perspective": ["perspective"],
|
|
625
|
+
"perspective-origin": ["perspective-origin"],
|
|
626
|
+
"place-content": ["align-content", "justify-content"],
|
|
627
|
+
"place-items": ["align-items", "justify-items"],
|
|
628
|
+
"place-self": ["align-self", "justify-self"],
|
|
629
|
+
"pointer-events": ["pointer-events"],
|
|
630
|
+
"position": ["position"],
|
|
631
|
+
"position-anchor": ["position-anchor"],
|
|
632
|
+
"position-area": ["position-area"],
|
|
633
|
+
"position-try": ["position-try-fallbacks", "position-try-order"],
|
|
634
|
+
"position-try-fallbacks": ["position-try-fallbacks"],
|
|
635
|
+
"position-try-order": ["position-try-order"],
|
|
636
|
+
"position-visibility": ["position-visibility"],
|
|
637
|
+
"print-color-adjust": ["print-color-adjust"],
|
|
638
|
+
"quotes": ["quotes"],
|
|
639
|
+
"r": ["r"],
|
|
640
|
+
"reading-flow": ["reading-flow"],
|
|
641
|
+
"reading-order": ["reading-order"],
|
|
642
|
+
"resize": ["resize"],
|
|
643
|
+
"right": ["right"],
|
|
644
|
+
"rotate": ["rotate"],
|
|
645
|
+
"row-gap": ["row-gap"],
|
|
646
|
+
"ruby-align": ["ruby-align"],
|
|
647
|
+
"ruby-merge": ["ruby-merge"],
|
|
648
|
+
"ruby-overhang": ["ruby-overhang"],
|
|
649
|
+
"ruby-position": ["ruby-position"],
|
|
650
|
+
"rx": ["rx"],
|
|
651
|
+
"ry": ["ry"],
|
|
652
|
+
"scale": ["scale"],
|
|
653
|
+
"scroll-axis-lock": ["scroll-axis-lock"],
|
|
654
|
+
"scroll-behavior": ["scroll-behavior"],
|
|
655
|
+
"scroll-initial-target": ["scroll-initial-target"],
|
|
656
|
+
"scroll-margin": ["scroll-margin-bottom", "scroll-margin-left", "scroll-margin-right", "scroll-margin-top"],
|
|
657
|
+
"scroll-margin-block": ["scroll-margin-block-end", "scroll-margin-block-start"],
|
|
658
|
+
"scroll-margin-block-end": ["scroll-margin-block-end"],
|
|
659
|
+
"scroll-margin-block-start": ["scroll-margin-block-start"],
|
|
660
|
+
"scroll-margin-bottom": ["scroll-margin-bottom"],
|
|
661
|
+
"scroll-margin-inline": ["scroll-margin-inline-end", "scroll-margin-inline-start"],
|
|
662
|
+
"scroll-margin-inline-end": ["scroll-margin-inline-end"],
|
|
663
|
+
"scroll-margin-inline-start": ["scroll-margin-inline-start"],
|
|
664
|
+
"scroll-margin-left": ["scroll-margin-left"],
|
|
665
|
+
"scroll-margin-right": ["scroll-margin-right"],
|
|
666
|
+
"scroll-margin-top": ["scroll-margin-top"],
|
|
667
|
+
"scroll-marker-group": ["scroll-marker-group"],
|
|
668
|
+
"scroll-padding": ["scroll-padding-bottom", "scroll-padding-left", "scroll-padding-right", "scroll-padding-top"],
|
|
669
|
+
"scroll-padding-block": ["scroll-padding-block-end", "scroll-padding-block-start"],
|
|
670
|
+
"scroll-padding-block-end": ["scroll-padding-block-end"],
|
|
671
|
+
"scroll-padding-block-start": ["scroll-padding-block-start"],
|
|
672
|
+
"scroll-padding-bottom": ["scroll-padding-bottom"],
|
|
673
|
+
"scroll-padding-inline": ["scroll-padding-inline-end", "scroll-padding-inline-start"],
|
|
674
|
+
"scroll-padding-inline-end": ["scroll-padding-inline-end"],
|
|
675
|
+
"scroll-padding-inline-start": ["scroll-padding-inline-start"],
|
|
676
|
+
"scroll-padding-left": ["scroll-padding-left"],
|
|
677
|
+
"scroll-padding-right": ["scroll-padding-right"],
|
|
678
|
+
"scroll-padding-top": ["scroll-padding-top"],
|
|
679
|
+
"scroll-snap-align": ["scroll-snap-align"],
|
|
680
|
+
"scroll-snap-coordinate": ["scroll-snap-coordinate"],
|
|
681
|
+
"scroll-snap-destination": ["scroll-snap-destination"],
|
|
682
|
+
"scroll-snap-points-x": ["scroll-snap-points-x"],
|
|
683
|
+
"scroll-snap-points-y": ["scroll-snap-points-y"],
|
|
684
|
+
"scroll-snap-stop": ["scroll-snap-stop"],
|
|
685
|
+
"scroll-snap-type": ["scroll-snap-type"],
|
|
686
|
+
"scroll-snap-type-x": ["scroll-snap-type-x"],
|
|
687
|
+
"scroll-snap-type-y": ["scroll-snap-type-y"],
|
|
688
|
+
"scroll-target-group": ["scroll-target-group"],
|
|
689
|
+
"scroll-timeline": ["scroll-timeline-axis", "scroll-timeline-name"],
|
|
690
|
+
"scroll-timeline-axis": ["scroll-timeline-axis"],
|
|
691
|
+
"scroll-timeline-name": ["scroll-timeline-name"],
|
|
692
|
+
"scrollbar-color": ["scrollbar-color"],
|
|
693
|
+
"scrollbar-gutter": ["scrollbar-gutter"],
|
|
694
|
+
"scrollbar-width": ["scrollbar-width"],
|
|
695
|
+
"shape-image-threshold": ["shape-image-threshold"],
|
|
696
|
+
"shape-margin": ["shape-margin"],
|
|
697
|
+
"shape-outside": ["shape-outside"],
|
|
698
|
+
"shape-rendering": ["shape-rendering"],
|
|
699
|
+
"speak-as": ["speak-as"],
|
|
700
|
+
"stop-color": ["stop-color"],
|
|
701
|
+
"stop-opacity": ["stop-opacity"],
|
|
702
|
+
"stroke": ["stroke"],
|
|
703
|
+
"stroke-color": ["stroke-color"],
|
|
704
|
+
"stroke-dasharray": ["stroke-dasharray"],
|
|
705
|
+
"stroke-dashoffset": ["stroke-dashoffset"],
|
|
706
|
+
"stroke-linecap": ["stroke-linecap"],
|
|
707
|
+
"stroke-linejoin": ["stroke-linejoin"],
|
|
708
|
+
"stroke-miterlimit": ["stroke-miterlimit"],
|
|
709
|
+
"stroke-opacity": ["stroke-opacity"],
|
|
710
|
+
"stroke-width": ["stroke-width"],
|
|
711
|
+
"tab-size": ["tab-size"],
|
|
712
|
+
"table-layout": ["table-layout"],
|
|
713
|
+
"text-align": ["text-align"],
|
|
714
|
+
"text-align-last": ["text-align-last"],
|
|
715
|
+
"text-anchor": ["text-anchor"],
|
|
716
|
+
"text-autospace": ["text-autospace"],
|
|
717
|
+
"text-box": ["text-box"],
|
|
718
|
+
"text-box-edge": ["text-box-edge"],
|
|
719
|
+
"text-box-trim": ["text-box-trim"],
|
|
720
|
+
"text-combine-upright": ["text-combine-upright"],
|
|
721
|
+
"text-decoration": ["text-decoration-color", "text-decoration-line", "text-decoration-style", "text-decoration-thickness"],
|
|
722
|
+
"text-decoration-color": ["text-decoration-color"],
|
|
723
|
+
"text-decoration-inset": ["text-decoration-inset"],
|
|
724
|
+
"text-decoration-line": ["text-decoration-line"],
|
|
725
|
+
"text-decoration-skip": ["text-decoration-skip"],
|
|
726
|
+
"text-decoration-skip-ink": ["text-decoration-skip-ink"],
|
|
727
|
+
"text-decoration-style": ["text-decoration-style"],
|
|
728
|
+
"text-decoration-thickness": ["text-decoration-thickness"],
|
|
729
|
+
"text-emphasis": ["text-emphasis-color", "text-emphasis-style"],
|
|
730
|
+
"text-emphasis-color": ["text-emphasis-color"],
|
|
731
|
+
"text-emphasis-position": ["text-emphasis-position"],
|
|
732
|
+
"text-emphasis-style": ["text-emphasis-style"],
|
|
733
|
+
"text-fit": ["text-fit"],
|
|
734
|
+
"text-indent": ["text-indent"],
|
|
735
|
+
"text-justify": ["text-justify"],
|
|
736
|
+
"text-orientation": ["text-orientation"],
|
|
737
|
+
"text-overflow": ["text-overflow"],
|
|
738
|
+
"text-rendering": ["text-rendering"],
|
|
739
|
+
"text-shadow": ["text-shadow"],
|
|
740
|
+
"text-size-adjust": ["text-size-adjust"],
|
|
741
|
+
"text-spacing-trim": ["text-spacing-trim"],
|
|
742
|
+
"text-transform": ["text-transform"],
|
|
743
|
+
"text-underline-offset": ["text-underline-offset"],
|
|
744
|
+
"text-underline-position": ["text-underline-position"],
|
|
745
|
+
"text-wrap": ["text-wrap-mode", "text-wrap-style"],
|
|
746
|
+
"text-wrap-mode": ["text-wrap-mode"],
|
|
747
|
+
"text-wrap-style": ["text-wrap-style"],
|
|
748
|
+
"timeline-scope": ["timeline-scope"],
|
|
749
|
+
"timeline-trigger": ["timeline-trigger-activation-range-end", "timeline-trigger-activation-range-start", "timeline-trigger-active-range-end", "timeline-trigger-active-range-start", "timeline-trigger-name", "timeline-trigger-source"],
|
|
750
|
+
"timeline-trigger-activation-range": ["timeline-trigger-activation-range-end", "timeline-trigger-activation-range-start"],
|
|
751
|
+
"timeline-trigger-activation-range-end": ["timeline-trigger-activation-range-end"],
|
|
752
|
+
"timeline-trigger-activation-range-start": ["timeline-trigger-activation-range-start"],
|
|
753
|
+
"timeline-trigger-active-range": ["timeline-trigger-active-range-end", "timeline-trigger-active-range-start"],
|
|
754
|
+
"timeline-trigger-active-range-end": ["timeline-trigger-active-range-end"],
|
|
755
|
+
"timeline-trigger-active-range-start": ["timeline-trigger-active-range-start"],
|
|
756
|
+
"timeline-trigger-name": ["timeline-trigger-name"],
|
|
757
|
+
"timeline-trigger-source": ["timeline-trigger-source"],
|
|
758
|
+
"top": ["top"],
|
|
759
|
+
"touch-action": ["touch-action"],
|
|
760
|
+
"transform": ["transform"],
|
|
761
|
+
"transform-box": ["transform-box"],
|
|
762
|
+
"transform-origin": ["transform-origin"],
|
|
763
|
+
"transform-style": ["transform-style"],
|
|
764
|
+
"transition": ["transition-behavior", "transition-delay", "transition-duration", "transition-property", "transition-timing-function"],
|
|
765
|
+
"transition-behavior": ["transition-behavior"],
|
|
766
|
+
"transition-delay": ["transition-delay"],
|
|
767
|
+
"transition-duration": ["transition-duration"],
|
|
768
|
+
"transition-property": ["transition-property"],
|
|
769
|
+
"transition-timing-function": ["transition-timing-function"],
|
|
770
|
+
"translate": ["translate"],
|
|
771
|
+
"trigger-scope": ["trigger-scope"],
|
|
772
|
+
"unicode-bidi": ["unicode-bidi"],
|
|
773
|
+
"user-select": ["user-select"],
|
|
774
|
+
"vector-effect": ["vector-effect"],
|
|
775
|
+
"vertical-align": ["vertical-align"],
|
|
776
|
+
"view-timeline": ["view-timeline-axis", "view-timeline-name"],
|
|
777
|
+
"view-timeline-axis": ["view-timeline-axis"],
|
|
778
|
+
"view-timeline-inset": ["view-timeline-inset"],
|
|
779
|
+
"view-timeline-name": ["view-timeline-name"],
|
|
780
|
+
"view-transition-class": ["view-transition-class"],
|
|
781
|
+
"view-transition-name": ["view-transition-name"],
|
|
782
|
+
"view-transition-scope": ["view-transition-scope"],
|
|
783
|
+
"visibility": ["visibility"],
|
|
784
|
+
"white-space": ["text-wrap-mode", "white-space-collapse", "white-space-trim"],
|
|
785
|
+
"white-space-collapse": ["white-space-collapse"],
|
|
786
|
+
"white-space-trim": ["white-space-trim"],
|
|
787
|
+
"widows": ["widows"],
|
|
788
|
+
"width": ["width"],
|
|
789
|
+
"will-change": ["will-change"],
|
|
790
|
+
"window-drag": ["window-drag"],
|
|
791
|
+
"word-break": ["word-break"],
|
|
792
|
+
"word-spacing": ["word-spacing"],
|
|
793
|
+
"word-wrap": ["word-wrap"],
|
|
794
|
+
"writing-mode": ["writing-mode"],
|
|
795
|
+
"x": ["x"],
|
|
796
|
+
"y": ["y"],
|
|
797
|
+
"z-index": ["z-index"],
|
|
798
|
+
"zoom": ["zoom"]
|
|
799
|
+
};
|
|
800
|
+
var LEGACY_ALIASES = {
|
|
801
|
+
"grid-column-gap": "column-gap",
|
|
802
|
+
"grid-gap": "gap",
|
|
803
|
+
"grid-row-gap": "row-gap",
|
|
804
|
+
"word-wrap": "overflow-wrap"
|
|
805
|
+
};
|
|
806
|
+
var LOGICAL_GROUPS = {
|
|
807
|
+
"size": { logical: ["block-size", "inline-size"], physical: ["height", "width"] },
|
|
808
|
+
"min-size": { logical: ["min-block-size", "min-inline-size"], physical: ["min-height", "min-width"] },
|
|
809
|
+
"max-size": { logical: ["max-block-size", "max-inline-size"], physical: ["max-height", "max-width"] },
|
|
810
|
+
"margin": { logical: ["margin-block-start", "margin-block-end", "margin-inline-start", "margin-inline-end"], physical: ["margin-top", "margin-right", "margin-bottom", "margin-left"] },
|
|
811
|
+
"padding": { logical: ["padding-block-start", "padding-block-end", "padding-inline-start", "padding-inline-end"], physical: ["padding-top", "padding-right", "padding-bottom", "padding-left"] },
|
|
812
|
+
"inset": { logical: ["inset-block-start", "inset-block-end", "inset-inline-start", "inset-inline-end"], physical: ["top", "right", "bottom", "left"] },
|
|
813
|
+
"border-width": { logical: ["border-block-start-width", "border-block-end-width", "border-inline-start-width", "border-inline-end-width"], physical: ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width"] },
|
|
814
|
+
"border-style": { logical: ["border-block-start-style", "border-block-end-style", "border-inline-start-style", "border-inline-end-style"], physical: ["border-top-style", "border-right-style", "border-bottom-style", "border-left-style"] },
|
|
815
|
+
"border-color": { logical: ["border-block-start-color", "border-block-end-color", "border-inline-start-color", "border-inline-end-color"], physical: ["border-top-color", "border-right-color", "border-bottom-color", "border-left-color"] },
|
|
816
|
+
"border-radius": { logical: ["border-start-start-radius", "border-start-end-radius", "border-end-start-radius", "border-end-end-radius"], physical: ["border-top-left-radius", "border-top-right-radius", "border-bottom-left-radius", "border-bottom-right-radius"] },
|
|
817
|
+
"overflow": { logical: ["overflow-block", "overflow-inline"], physical: ["overflow-x", "overflow-y"] },
|
|
818
|
+
"overscroll-behavior": { logical: ["overscroll-behavior-block", "overscroll-behavior-inline"], physical: ["overscroll-behavior-x", "overscroll-behavior-y"] },
|
|
819
|
+
"scroll-padding": { logical: ["scroll-padding-block-start", "scroll-padding-block-end", "scroll-padding-inline-start", "scroll-padding-inline-end"], physical: ["scroll-padding-top", "scroll-padding-right", "scroll-padding-bottom", "scroll-padding-left"] },
|
|
820
|
+
"scroll-margin": { logical: ["scroll-margin-block-start", "scroll-margin-block-end", "scroll-margin-inline-start", "scroll-margin-inline-end"], physical: ["scroll-margin-top", "scroll-margin-right", "scroll-margin-bottom", "scroll-margin-left"] },
|
|
821
|
+
"contain-intrinsic-size": { logical: ["contain-intrinsic-block-size", "contain-intrinsic-inline-size"], physical: ["contain-intrinsic-height", "contain-intrinsic-width"] }
|
|
822
|
+
};
|
|
823
|
+
|
|
824
|
+
// src/directive/property-relations.ts
|
|
825
|
+
var VENDOR_PREFIXED = /^-(?:webkit|moz|ms|o)-[a-z0-9-]+$/;
|
|
826
|
+
var ALIASES = new Map(Object.entries(LEGACY_ALIASES));
|
|
827
|
+
var LONGHAND_LISTS = new Map(Object.entries(PROPERTY_LONGHANDS));
|
|
828
|
+
var LONGHAND_SETS = new Map(
|
|
829
|
+
Object.entries(PROPERTY_LONGHANDS).map(([name, longhands]) => [name, new Set(longhands)])
|
|
830
|
+
);
|
|
831
|
+
var GROUP_OF_LONGHAND = new Map(
|
|
832
|
+
Object.entries(LOGICAL_GROUPS).flatMap(([group, { logical, physical }]) => [
|
|
833
|
+
...logical.map((name) => [
|
|
834
|
+
name,
|
|
835
|
+
{ logical: true, group }
|
|
836
|
+
]),
|
|
837
|
+
...physical.map((name) => [
|
|
838
|
+
name,
|
|
839
|
+
{ logical: false, group }
|
|
840
|
+
])
|
|
841
|
+
])
|
|
842
|
+
);
|
|
843
|
+
function isCustomProperty(name) {
|
|
844
|
+
return name.startsWith("--") && name.length > 2;
|
|
845
|
+
}
|
|
846
|
+
function foldAscii(name) {
|
|
847
|
+
return name.replaceAll(/[A-Z]+/g, (letters) => letters.toLowerCase());
|
|
848
|
+
}
|
|
849
|
+
function standardName(name) {
|
|
850
|
+
if (isCustomProperty(name)) return name;
|
|
851
|
+
const folded = foldAscii(name);
|
|
852
|
+
return ALIASES.get(folded) ?? folded;
|
|
853
|
+
}
|
|
854
|
+
function isSameProperty(a, b) {
|
|
855
|
+
return standardName(a) === standardName(b);
|
|
856
|
+
}
|
|
857
|
+
function knownLonghands(name) {
|
|
858
|
+
return LONGHAND_SETS.get(foldAscii(name));
|
|
859
|
+
}
|
|
860
|
+
function isCssProperty(name) {
|
|
861
|
+
return isCustomProperty(name) || VENDOR_PREFIXED.test(foldAscii(name)) || knownLonghands(name) !== void 0;
|
|
862
|
+
}
|
|
863
|
+
function longhandsOf(name) {
|
|
864
|
+
if (isCustomProperty(name)) return [name];
|
|
865
|
+
const folded = foldAscii(name);
|
|
866
|
+
if (VENDOR_PREFIXED.test(folded)) return [folded];
|
|
867
|
+
return LONGHAND_LISTS.get(folded) ?? [];
|
|
868
|
+
}
|
|
869
|
+
function haveCommonMember(a, b) {
|
|
870
|
+
const [smaller, larger] = a.size <= b.size ? [a, b] : [b, a];
|
|
871
|
+
return [...smaller].some((member) => larger.has(member));
|
|
872
|
+
}
|
|
873
|
+
function sidesOf(longhands) {
|
|
874
|
+
const sides = /* @__PURE__ */ new Map();
|
|
875
|
+
for (const longhand of longhands) {
|
|
876
|
+
const member = GROUP_OF_LONGHAND.get(longhand);
|
|
877
|
+
if (member === void 0) continue;
|
|
878
|
+
const side = member.logical ? "logical" : "physical";
|
|
879
|
+
const known = sides.get(member.group);
|
|
880
|
+
sides.set(member.group, known === void 0 || known === side ? side : "both");
|
|
881
|
+
}
|
|
882
|
+
return sides;
|
|
883
|
+
}
|
|
884
|
+
function isLogicalPhysicalPair(a, b) {
|
|
885
|
+
const first = knownLonghands(a);
|
|
886
|
+
const second = knownLonghands(b);
|
|
887
|
+
if (first === void 0 || second === void 0 || foldAscii(a) === foldAscii(b)) return false;
|
|
888
|
+
const secondSides = sidesOf(second);
|
|
889
|
+
return [...sidesOf(first)].some(([group, side]) => {
|
|
890
|
+
const other = secondSides.get(group);
|
|
891
|
+
return other !== void 0 && side !== "both" && other !== "both" && side !== other;
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
function propertiesRelate(a, b) {
|
|
895
|
+
if (isCustomProperty(a) || isCustomProperty(b)) return a === b;
|
|
896
|
+
const first = standardName(a);
|
|
897
|
+
const second = standardName(b);
|
|
898
|
+
if (first === second) return true;
|
|
899
|
+
if (VENDOR_PREFIXED.test(first) || VENDOR_PREFIXED.test(second)) return false;
|
|
900
|
+
const firstLonghands = LONGHAND_SETS.get(first);
|
|
901
|
+
const secondLonghands = LONGHAND_SETS.get(second);
|
|
902
|
+
if (firstLonghands === void 0 || secondLonghands === void 0) return false;
|
|
903
|
+
return haveCommonMember(firstLonghands, secondLonghands) || isLogicalPhysicalPair(first, second);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
// src/directive/selector-compounds.ts
|
|
907
|
+
var OPENERS2 = /* @__PURE__ */ new Set(["(-token", "[-token", "function-token", "{-token"]);
|
|
908
|
+
var CLOSERS = /* @__PURE__ */ new Set([")-token", "]-token", "}-token"]);
|
|
909
|
+
var COMBINATOR_DELIMS = /* @__PURE__ */ new Set(["+", ">", "~"]);
|
|
910
|
+
var LEGACY_PSEUDO_ELEMENTS = /* @__PURE__ */ new Set(["after", "before", "first-letter", "first-line"]);
|
|
911
|
+
function isDelim(token, value) {
|
|
912
|
+
return token?.type === "delim-token" && token.raw === value;
|
|
913
|
+
}
|
|
914
|
+
function isTypeName(token) {
|
|
915
|
+
return token?.type === "ident-token" || isDelim(token, "*");
|
|
916
|
+
}
|
|
917
|
+
function groupEnd(tokens, start) {
|
|
918
|
+
let depth = 1;
|
|
919
|
+
let index = start + 1;
|
|
920
|
+
while (index < tokens.length) {
|
|
921
|
+
const { type } = tokens[index];
|
|
922
|
+
if (OPENERS2.has(type)) depth += 1;
|
|
923
|
+
else if (CLOSERS.has(type)) depth -= 1;
|
|
924
|
+
if (depth === 0) return index;
|
|
925
|
+
index += 1;
|
|
926
|
+
}
|
|
927
|
+
return tokens.length;
|
|
928
|
+
}
|
|
929
|
+
function readTypeSelector(tokens, index) {
|
|
930
|
+
let nameIndex = index;
|
|
931
|
+
if (isTypeName(tokens[index]) && isDelim(tokens[index + 1], "|") && isTypeName(tokens[index + 2])) {
|
|
932
|
+
nameIndex = index + 2;
|
|
933
|
+
} else if (isDelim(tokens[index], "|") && isTypeName(tokens[index + 1])) {
|
|
934
|
+
nameIndex = index + 1;
|
|
935
|
+
}
|
|
936
|
+
const kind = isDelim(tokens[nameIndex], "*") ? "universal" : "type";
|
|
937
|
+
return { simple: { kind }, next: nameIndex + 1 };
|
|
938
|
+
}
|
|
939
|
+
function readIdentPseudo(name, nameIndex, isElement) {
|
|
940
|
+
const lowered = name.raw.toLowerCase();
|
|
941
|
+
const isPseudoElement = isElement || LEGACY_PSEUDO_ELEMENTS.has(lowered);
|
|
942
|
+
const simple = isPseudoElement ? { kind: "pseudo-element", args: [], name: lowered } : { kind: "class" };
|
|
943
|
+
return { simple, next: nameIndex + 1 };
|
|
944
|
+
}
|
|
945
|
+
function readFunctionPseudo(tokens, nameIndex, isElement) {
|
|
946
|
+
const end = groupEnd(tokens, nameIndex);
|
|
947
|
+
const name = tokens[nameIndex].structured.value.toLowerCase();
|
|
948
|
+
const args = tokens.slice(nameIndex + 1, end);
|
|
949
|
+
const kind = isElement ? "pseudo-element" : "function";
|
|
950
|
+
return { simple: { kind, args, name }, next: end + 1 };
|
|
951
|
+
}
|
|
952
|
+
function readPseudo(tokens, index) {
|
|
953
|
+
const isElement = tokens[index + 1]?.type === "colon-token";
|
|
954
|
+
const nameIndex = index + (isElement ? 2 : 1);
|
|
955
|
+
const name = tokens[nameIndex];
|
|
956
|
+
if (name?.type === "ident-token") return readIdentPseudo(name, nameIndex, isElement);
|
|
957
|
+
if (name?.type === "function-token") return readFunctionPseudo(tokens, nameIndex, isElement);
|
|
958
|
+
return { next: nameIndex };
|
|
959
|
+
}
|
|
960
|
+
function readSimple(tokens, index) {
|
|
961
|
+
const token = tokens[index];
|
|
962
|
+
if (isDelim(token, "&")) return { simple: { kind: "nesting" }, next: index + 1 };
|
|
963
|
+
if (isTypeName(token) || isDelim(token, "|")) return readTypeSelector(tokens, index);
|
|
964
|
+
if (isDelim(token, ".") && tokens[index + 1]?.type === "ident-token") {
|
|
965
|
+
return { simple: { kind: "class" }, next: index + 2 };
|
|
966
|
+
}
|
|
967
|
+
if (token.type === "hash-token") return { simple: { kind: "id" }, next: index + 1 };
|
|
968
|
+
if (token.type === "[-token")
|
|
969
|
+
return { simple: { kind: "class" }, next: groupEnd(tokens, index) + 1 };
|
|
970
|
+
if (token.type === "colon-token") return readPseudo(tokens, index);
|
|
971
|
+
return { next: index + 1 };
|
|
972
|
+
}
|
|
973
|
+
function isCombinator(token) {
|
|
974
|
+
return token.type === "whitespace-token" || token.type === "delim-token" && COMBINATOR_DELIMS.has(token.raw);
|
|
975
|
+
}
|
|
976
|
+
function parseComplex(tokens) {
|
|
977
|
+
const compounds = [];
|
|
978
|
+
let current = [];
|
|
979
|
+
let index = 0;
|
|
980
|
+
while (index < tokens.length) {
|
|
981
|
+
if (isCombinator(tokens[index])) {
|
|
982
|
+
if (current.length > 0) compounds.push(current);
|
|
983
|
+
current = [];
|
|
984
|
+
index += 1;
|
|
985
|
+
continue;
|
|
986
|
+
}
|
|
987
|
+
const read = readSimple(tokens, index);
|
|
988
|
+
if (read.simple) current.push(read.simple);
|
|
989
|
+
index = read.next;
|
|
990
|
+
}
|
|
991
|
+
if (current.length > 0) compounds.push(current);
|
|
992
|
+
return compounds;
|
|
993
|
+
}
|
|
994
|
+
function splitOnCommas(tokens) {
|
|
995
|
+
const parts = [[]];
|
|
996
|
+
let index = 0;
|
|
997
|
+
while (index < tokens.length) {
|
|
998
|
+
const token = tokens[index];
|
|
999
|
+
if (token.type === "comma-token") {
|
|
1000
|
+
parts.push([]);
|
|
1001
|
+
index += 1;
|
|
1002
|
+
continue;
|
|
1003
|
+
}
|
|
1004
|
+
const end = OPENERS2.has(token.type) ? groupEnd(tokens, index) : index;
|
|
1005
|
+
parts.at(-1).push(...tokens.slice(index, end + 1));
|
|
1006
|
+
index = end + 1;
|
|
1007
|
+
}
|
|
1008
|
+
return parts;
|
|
1009
|
+
}
|
|
1010
|
+
function codeTokens(text) {
|
|
1011
|
+
return tokenize(text).filter((token) => token.type !== "comment");
|
|
1012
|
+
}
|
|
1013
|
+
function parseSelectorTokens(tokens) {
|
|
1014
|
+
return splitOnCommas(tokens).map((part) => parseComplex(part)).filter((complex) => complex.length > 0);
|
|
1015
|
+
}
|
|
1016
|
+
function parseSelectorList(selectorList) {
|
|
1017
|
+
return parseSelectorTokens(codeTokens(selectorList));
|
|
1018
|
+
}
|
|
1019
|
+
function tokensAfterOf(args) {
|
|
1020
|
+
const ofIndex = args.findIndex(
|
|
1021
|
+
(token, index) => token.type === "ident-token" && token.raw.toLowerCase() === "of" && args[index - 1]?.type === "whitespace-token"
|
|
1022
|
+
);
|
|
1023
|
+
return ofIndex === -1 ? [] : args.slice(ofIndex + 1);
|
|
1024
|
+
}
|
|
1025
|
+
function subjectOf(complex) {
|
|
1026
|
+
return complex.at(-1) ?? [];
|
|
1027
|
+
}
|
|
1028
|
+
function hasPseudoElement(compound) {
|
|
1029
|
+
return compound.some((simple) => simple.kind === "pseudo-element");
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
// src/directive/selector-specificity.ts
|
|
1033
|
+
var ZERO = [0, 0, 0];
|
|
1034
|
+
var ONE_CLASS = [0, 1, 0];
|
|
1035
|
+
var ONE_TYPE = [0, 0, 1];
|
|
1036
|
+
var ONE_ID = [1, 0, 0];
|
|
1037
|
+
var FIXED_WEIGHTS = {
|
|
1038
|
+
class: ONE_CLASS,
|
|
1039
|
+
id: ONE_ID,
|
|
1040
|
+
type: ONE_TYPE,
|
|
1041
|
+
universal: ZERO
|
|
1042
|
+
};
|
|
1043
|
+
var ARGUMENT_MAX_PSEUDOS = /* @__PURE__ */ new Set(["has", "is", "not"]);
|
|
1044
|
+
var NTH_PSEUDOS = /* @__PURE__ */ new Set(["nth-child", "nth-last-child"]);
|
|
1045
|
+
var SUBJECT_TRANSPARENT_PSEUDOS = /* @__PURE__ */ new Set(["is", "where"]);
|
|
1046
|
+
var MAX_NESTING = 256;
|
|
1047
|
+
var UnreadableSelector = class extends Error {
|
|
1048
|
+
};
|
|
1049
|
+
function deeper(depth) {
|
|
1050
|
+
if (depth >= MAX_NESTING) throw new UnreadableSelector("selector nests too deep to be read");
|
|
1051
|
+
return depth + 1;
|
|
1052
|
+
}
|
|
1053
|
+
function compareSpecificity(a, b) {
|
|
1054
|
+
return a[0] - b[0] || a[1] - b[1] || a[2] - b[2];
|
|
1055
|
+
}
|
|
1056
|
+
function addSpecificity(a, b) {
|
|
1057
|
+
return [a[0] + b[0], a[1] + b[1], a[2] + b[2]];
|
|
1058
|
+
}
|
|
1059
|
+
function maxSpecificity(specificities) {
|
|
1060
|
+
return specificities.reduce(
|
|
1061
|
+
(heaviest, next) => compareSpecificity(next, heaviest) > 0 ? next : heaviest,
|
|
1062
|
+
ZERO
|
|
1063
|
+
);
|
|
1064
|
+
}
|
|
1065
|
+
function pseudoElementSpecificity(name, args, weigh) {
|
|
1066
|
+
if (name !== "slotted") return ONE_TYPE;
|
|
1067
|
+
const argument = listSpecificity(parseSelectorTokens(args), {
|
|
1068
|
+
...weigh,
|
|
1069
|
+
depth: deeper(weigh.depth)
|
|
1070
|
+
});
|
|
1071
|
+
return addSpecificity(ONE_TYPE, argument);
|
|
1072
|
+
}
|
|
1073
|
+
function functionSpecificity(name, args, weigh) {
|
|
1074
|
+
if (name === "where") return ZERO;
|
|
1075
|
+
const inner = { ...weigh, depth: deeper(weigh.depth) };
|
|
1076
|
+
if (ARGUMENT_MAX_PSEUDOS.has(name)) return listSpecificity(parseSelectorTokens(args), inner);
|
|
1077
|
+
if (!NTH_PSEUDOS.has(name)) return ONE_CLASS;
|
|
1078
|
+
const argument = listSpecificity(parseSelectorTokens(tokensAfterOf(args)), inner);
|
|
1079
|
+
return addSpecificity(ONE_CLASS, argument);
|
|
1080
|
+
}
|
|
1081
|
+
function simpleSpecificity(simple, weigh) {
|
|
1082
|
+
if (simple.kind === "nesting") return weigh.amp;
|
|
1083
|
+
if (simple.kind === "function") return functionSpecificity(simple.name, simple.args, weigh);
|
|
1084
|
+
if (simple.kind === "pseudo-element")
|
|
1085
|
+
return pseudoElementSpecificity(simple.name, simple.args, weigh);
|
|
1086
|
+
return FIXED_WEIGHTS[simple.kind];
|
|
1087
|
+
}
|
|
1088
|
+
function complexSpecificity(complex, weigh) {
|
|
1089
|
+
return complex.flat().reduce((sum, simple) => addSpecificity(sum, simpleSpecificity(simple, weigh)), ZERO);
|
|
1090
|
+
}
|
|
1091
|
+
function listSpecificity(list, weigh) {
|
|
1092
|
+
return maxSpecificity(list.map((complex) => complexSpecificity(complex, weigh)));
|
|
1093
|
+
}
|
|
1094
|
+
function isSubjectOnAmpersandElement(compound, depth) {
|
|
1095
|
+
return compound.some((simple) => {
|
|
1096
|
+
if (simple.kind === "nesting") return true;
|
|
1097
|
+
if (simple.kind !== "function" || !SUBJECT_TRANSPARENT_PSEUDOS.has(simple.name)) return false;
|
|
1098
|
+
const inner = deeper(depth);
|
|
1099
|
+
return parseSelectorTokens(simple.args).some(
|
|
1100
|
+
(arm) => isSubjectOnAmpersandElement(subjectOf(arm), inner)
|
|
1101
|
+
);
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
1104
|
+
function isComplexEndingInPseudoElement(complex) {
|
|
1105
|
+
return hasPseudoElement(subjectOf(complex));
|
|
1106
|
+
}
|
|
1107
|
+
function endsInPseudoElement(complexSelector) {
|
|
1108
|
+
return parseSelectorList(complexSelector).some(
|
|
1109
|
+
(complex) => isComplexEndingInPseudoElement(complex)
|
|
1110
|
+
);
|
|
1111
|
+
}
|
|
1112
|
+
function isPseudoElementOnlyList(selectorList) {
|
|
1113
|
+
const list = parseSelectorList(selectorList);
|
|
1114
|
+
return list.length > 0 && list.every((complex) => isComplexEndingInPseudoElement(complex));
|
|
1115
|
+
}
|
|
1116
|
+
function ampersandSpecificity(parentSelectorList) {
|
|
1117
|
+
const onElement = parseSelectorList(parentSelectorList).filter(
|
|
1118
|
+
(complex) => !isComplexEndingInPseudoElement(complex)
|
|
1119
|
+
);
|
|
1120
|
+
try {
|
|
1121
|
+
return listSpecificity(onElement, { amp: ONE_CLASS, depth: 0 });
|
|
1122
|
+
} catch (error) {
|
|
1123
|
+
if (error instanceof UnreadableSelector) return ZERO;
|
|
1124
|
+
throw error;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
function nestedSpecificities(selector, amp) {
|
|
1128
|
+
try {
|
|
1129
|
+
return parseSelectorList(selector).filter(
|
|
1130
|
+
(complex) => !isComplexEndingInPseudoElement(complex) && isSubjectOnAmpersandElement(subjectOf(complex), 0)
|
|
1131
|
+
).map((complex) => complexSpecificity(complex, { amp, depth: 0 }));
|
|
1132
|
+
} catch (error) {
|
|
1133
|
+
if (error instanceof UnreadableSelector) return [];
|
|
1134
|
+
throw error;
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
// src/directive/value-equality.ts
|
|
1139
|
+
function foldAscii2(name) {
|
|
1140
|
+
return name.replaceAll(/[A-Z]+/g, (letters) => letters.toLowerCase());
|
|
1141
|
+
}
|
|
1142
|
+
function tokenKey(token) {
|
|
1143
|
+
if (token.type === "whitespace-token") return "ws";
|
|
1144
|
+
const isFoldable = token.type === "function-token" && !token.raw.startsWith("--");
|
|
1145
|
+
return `${token.type}:${isFoldable ? foldAscii2(token.raw) : token.raw}`;
|
|
1146
|
+
}
|
|
1147
|
+
function normalizedKeys(value) {
|
|
1148
|
+
const keys = [];
|
|
1149
|
+
for (const token of tokenize(value)) {
|
|
1150
|
+
if (token.type === "comment") continue;
|
|
1151
|
+
const key = tokenKey(token);
|
|
1152
|
+
if (key === "ws" && (keys.length === 0 || keys.at(-1) === "ws")) continue;
|
|
1153
|
+
keys.push(key);
|
|
1154
|
+
}
|
|
1155
|
+
if (keys.at(-1) === "ws") keys.pop();
|
|
1156
|
+
return keys;
|
|
1157
|
+
}
|
|
1158
|
+
function normalizeValueForCompare(value) {
|
|
1159
|
+
return JSON.stringify(normalizedKeys(value));
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
// src/directive/order-compare.ts
|
|
1163
|
+
var VALUE_KEYS = /* @__PURE__ */ new WeakMap();
|
|
1164
|
+
function valueKey(declaration) {
|
|
1165
|
+
let key = VALUE_KEYS.get(declaration);
|
|
1166
|
+
if (key === void 0) {
|
|
1167
|
+
key = normalizeValueForCompare(declaration.value);
|
|
1168
|
+
VALUE_KEYS.set(declaration, key);
|
|
1169
|
+
}
|
|
1170
|
+
return key;
|
|
1171
|
+
}
|
|
1172
|
+
function relatedPairs(unit, candidate) {
|
|
1173
|
+
const later = candidate.declaration;
|
|
1174
|
+
if (later.important) return [];
|
|
1175
|
+
return unit.declarations.filter((block) => !block.important && propertiesRelate(block.prop, later.prop)).filter(
|
|
1176
|
+
(block) => !isSameProperty(block.prop, later.prop) || valueKey(block) !== valueKey(later)
|
|
1177
|
+
).map((block) => ({ block, later }));
|
|
1178
|
+
}
|
|
1179
|
+
function haveEqualSpecificity(a, b) {
|
|
1180
|
+
return a.some((x) => b.some((y) => compareSpecificity(x, y) === 0));
|
|
1181
|
+
}
|
|
1182
|
+
function compare(unit, candidate) {
|
|
1183
|
+
if (!haveEqualSpecificity(unit.specificities, candidate.specificities)) return void 0;
|
|
1184
|
+
if (!conditionsMayOverlap(unit.conditions, candidate.conditions)) return void 0;
|
|
1185
|
+
const pairs2 = relatedPairs(unit, candidate);
|
|
1186
|
+
return pairs2.length === 0 ? void 0 : { unit, candidate, pairs: pairs2 };
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
// src/directive/order-moves.ts
|
|
1190
|
+
var MOVE_LIMIT = 50;
|
|
1191
|
+
function pairKey({ candidate, unit }) {
|
|
1192
|
+
const { overrider } = candidate;
|
|
1193
|
+
const who = overrider.kind === "atom" ? ["atom", overrider.directive.ref, overrider.atom.atomIndex, overrider.isBlock] : ["own", overrider.topRef];
|
|
1194
|
+
return JSON.stringify([
|
|
1195
|
+
unit.directive.ref,
|
|
1196
|
+
unit.atom.atomIndex,
|
|
1197
|
+
unit.selector,
|
|
1198
|
+
unit.conditions,
|
|
1199
|
+
unit.declarations,
|
|
1200
|
+
who,
|
|
1201
|
+
candidate.declaration,
|
|
1202
|
+
candidate.holderSelector,
|
|
1203
|
+
candidate.conditions
|
|
1204
|
+
]);
|
|
1205
|
+
}
|
|
1206
|
+
var ownNode = (ref) => (segment) => segment.kind === "own" && segment.node.ref === ref;
|
|
1207
|
+
var ofDirective = (ref) => (segment) => segment.kind !== "own" && segment.directive.ref === ref;
|
|
1208
|
+
var ofAtom = (ref, atomIndex) => (segment) => segment.kind !== "own" && segment.directive.ref === ref && segment.atom.atomIndex === atomIndex;
|
|
1209
|
+
var namedAtom = (ref, name) => (segment) => segment.kind !== "own" && segment.directive.ref === ref && segment.atom.name === name;
|
|
1210
|
+
function relocated(segments, isMoved, place) {
|
|
1211
|
+
const moved = segments.filter((segment) => isMoved(segment));
|
|
1212
|
+
const rest = segments.filter((segment) => !isMoved(segment));
|
|
1213
|
+
const index = "before" in place ? rest.findIndex((segment) => place.before(segment)) : rest.findLastIndex((segment) => place.after(segment));
|
|
1214
|
+
if (index === -1 || moved.length === 0) return void 0;
|
|
1215
|
+
const at = "before" in place ? index : index + 1;
|
|
1216
|
+
return {
|
|
1217
|
+
arranged: [...rest.slice(0, at), ...moved, ...rest.slice(at)],
|
|
1218
|
+
moved: new Set(moved)
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
function moveOf(relocation, key) {
|
|
1222
|
+
return relocation && {
|
|
1223
|
+
arranged: relocation.arranged,
|
|
1224
|
+
key,
|
|
1225
|
+
scope: { kind: "moved", segments: relocation.moved }
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1228
|
+
function lastOverriderIndex(finding, all) {
|
|
1229
|
+
const { unit, candidate } = finding;
|
|
1230
|
+
if (candidate.overrider.kind !== "atom" || candidate.overrider.directive.ref !== unit.directive.ref) {
|
|
1231
|
+
return void 0;
|
|
1232
|
+
}
|
|
1233
|
+
const indexes = all.filter(
|
|
1234
|
+
(other) => other.unit.directive.ref === unit.directive.ref && other.unit.atom.name === unit.atom.name
|
|
1235
|
+
).flatMap(
|
|
1236
|
+
(other) => other.candidate.overrider.kind === "atom" && other.candidate.overrider.directive.ref === unit.directive.ref ? [other.candidate.overrider.atom.atomIndex] : []
|
|
1237
|
+
);
|
|
1238
|
+
return Math.max(...indexes);
|
|
1239
|
+
}
|
|
1240
|
+
function childrenMoved(children, moving, before) {
|
|
1241
|
+
const node = children.find((child) => child.ref === moving);
|
|
1242
|
+
const rest = children.filter((child) => child.ref !== moving);
|
|
1243
|
+
const at = rest.findIndex((child) => child.ref === before);
|
|
1244
|
+
if (node === void 0 || at === -1) return void 0;
|
|
1245
|
+
return [...rest.slice(0, at), node, ...rest.slice(at)];
|
|
1246
|
+
}
|
|
1247
|
+
function groupWithChildMoved(root, at) {
|
|
1248
|
+
if (root.kind !== "group") return void 0;
|
|
1249
|
+
const stack = [{ node: root, next: 0 }];
|
|
1250
|
+
while (stack.length > 0 && stack.at(-1).node.ref !== at.group) {
|
|
1251
|
+
const frame = stack.at(-1);
|
|
1252
|
+
const child = frame.node.nodes[frame.next++];
|
|
1253
|
+
if (child === void 0) stack.pop();
|
|
1254
|
+
else if (child.kind === "group") stack.push({ node: child, next: 0 });
|
|
1255
|
+
}
|
|
1256
|
+
const target = stack.at(-1);
|
|
1257
|
+
const moved = target && childrenMoved(target.node.nodes, at.moving, at.before);
|
|
1258
|
+
if (target === void 0 || moved === void 0) return void 0;
|
|
1259
|
+
let rebuilt = { ...target.node, nodes: moved };
|
|
1260
|
+
for (let i = stack.length - 2; i >= 0; i--) {
|
|
1261
|
+
const replaced = stack[i + 1].node;
|
|
1262
|
+
rebuilt = {
|
|
1263
|
+
...stack[i].node,
|
|
1264
|
+
nodes: stack[i].node.nodes.map((child) => child === replaced ? rebuilt : child)
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1267
|
+
return rebuilt;
|
|
1268
|
+
}
|
|
1269
|
+
function outwardMove(finding, segments) {
|
|
1270
|
+
const { outward, candidate } = finding;
|
|
1271
|
+
const { overrider } = candidate;
|
|
1272
|
+
if (outward === void 0) return void 0;
|
|
1273
|
+
const { level, top } = outward;
|
|
1274
|
+
const mover = overrider.kind === "own" ? `own:${overrider.topRef}` : `directive:${overrider.directive.ref}`;
|
|
1275
|
+
const key = JSON.stringify(["outward", top, level, mover]);
|
|
1276
|
+
if (level === void 0) {
|
|
1277
|
+
const moving = overrider.kind === "own" ? ownNode(overrider.topRef) : ofDirective(overrider.directive.ref);
|
|
1278
|
+
return moveOf(relocated(segments, moving, { before: ownNode(top) }), key);
|
|
1279
|
+
}
|
|
1280
|
+
const holder = segments.find(ownNode(top));
|
|
1281
|
+
if (holder?.kind !== "own" || overrider.kind !== "own") return void 0;
|
|
1282
|
+
const rebuilt = groupWithChildMoved(holder.node, {
|
|
1283
|
+
before: level.container,
|
|
1284
|
+
group: level.group,
|
|
1285
|
+
moving: overrider.topRef
|
|
1286
|
+
});
|
|
1287
|
+
if (rebuilt === void 0) return void 0;
|
|
1288
|
+
const regrouped = { ...holder, node: rebuilt };
|
|
1289
|
+
const arranged = segments.map((segment) => segment === holder ? regrouped : segment);
|
|
1290
|
+
return { arranged, key, scope: { child: overrider.topRef, kind: "child", top: regrouped } };
|
|
1291
|
+
}
|
|
1292
|
+
function ruleMove(finding, segments, all) {
|
|
1293
|
+
const { candidate, unit } = finding;
|
|
1294
|
+
const { overrider } = candidate;
|
|
1295
|
+
if (overrider.kind === "own") {
|
|
1296
|
+
const relocation2 = relocated(segments, ownNode(overrider.topRef), {
|
|
1297
|
+
before: ofDirective(unit.directive.ref)
|
|
1298
|
+
});
|
|
1299
|
+
return moveOf(relocation2, `own:${overrider.topRef}:${unit.directive.ref}`);
|
|
1300
|
+
}
|
|
1301
|
+
const index = lastOverriderIndex(finding, all) ?? overrider.atom.atomIndex;
|
|
1302
|
+
const relocation = relocated(segments, namedAtom(unit.directive.ref, unit.atom.name), {
|
|
1303
|
+
after: ofAtom(overrider.directive.ref, index)
|
|
1304
|
+
});
|
|
1305
|
+
const key = `atom:${unit.directive.ref}:${unit.atom.name}:${overrider.directive.ref}:${index}`;
|
|
1306
|
+
return moveOf(relocation, key);
|
|
1307
|
+
}
|
|
1308
|
+
function markMoves(findings, segments, recheck) {
|
|
1309
|
+
if (findings.length > MOVE_LIMIT)
|
|
1310
|
+
return findings.map((finding) => ({ ...finding, canMove: () => false }));
|
|
1311
|
+
let before;
|
|
1312
|
+
const after = /* @__PURE__ */ new Map();
|
|
1313
|
+
const isClear = (finding) => {
|
|
1314
|
+
const move = finding.outward ? outwardMove(finding, segments) : ruleMove(finding, segments, findings);
|
|
1315
|
+
if (move === void 0) return false;
|
|
1316
|
+
before ??= new Set(findings.map((found) => pairKey(found)));
|
|
1317
|
+
if (!after.has(move.key)) {
|
|
1318
|
+
const found = recheck(move.arranged, move.scope);
|
|
1319
|
+
after.set(move.key, new Set(found.map((pair) => pairKey(pair))));
|
|
1320
|
+
}
|
|
1321
|
+
const pairs2 = after.get(move.key);
|
|
1322
|
+
return !pairs2.has(pairKey(finding)) && [...pairs2].every((key) => before.has(key));
|
|
1323
|
+
};
|
|
1324
|
+
return findings.map((finding) => {
|
|
1325
|
+
let known;
|
|
1326
|
+
return { ...finding, canMove: () => known ??= isClear(finding) };
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
// src/directive/order-declaration.ts
|
|
1331
|
+
function lastSignificant(tokens, before) {
|
|
1332
|
+
let i = before - 1;
|
|
1333
|
+
while (i >= 0 && (tokens[i].type === "whitespace-token" || tokens[i].type === "comment")) i--;
|
|
1334
|
+
return i;
|
|
1335
|
+
}
|
|
1336
|
+
function toOrderDeclaration(declaration) {
|
|
1337
|
+
const tokens = tokenize(declaration.value);
|
|
1338
|
+
const last = lastSignificant(tokens, tokens.length);
|
|
1339
|
+
const ident = tokens[last];
|
|
1340
|
+
if (ident?.type !== "ident-token" || String(ident.structured?.value).toLowerCase() !== "important") {
|
|
1341
|
+
return { prop: declaration.prop, value: declaration.value, important: false };
|
|
1342
|
+
}
|
|
1343
|
+
const bang = lastSignificant(tokens, last);
|
|
1344
|
+
if (tokens[bang]?.type !== "delim-token" || tokens[bang].structured?.value !== "!") {
|
|
1345
|
+
return { prop: declaration.prop, value: declaration.value, important: false };
|
|
1346
|
+
}
|
|
1347
|
+
const value = declaration.value.slice(0, tokens[bang].startIndex).trim();
|
|
1348
|
+
return { prop: declaration.prop, value, important: true };
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
// src/directive/order-marker.ts
|
|
1352
|
+
var MARKER_HEAD = "nave-allow-override";
|
|
1353
|
+
function parseMarker(body, start, end) {
|
|
1354
|
+
const rest = body.slice(MARKER_HEAD.length + 1);
|
|
1355
|
+
const separator = rest.search(/(?:^|\s)--(?:\s|$)/);
|
|
1356
|
+
const namesText = separator === -1 ? rest : rest.slice(0, separator);
|
|
1357
|
+
const reason = separator === -1 ? void 0 : rest.slice(separator).replace(/^\s*--/, "").trim();
|
|
1358
|
+
return { start, end, names: namesText.split(/\s+/).filter(Boolean), reason };
|
|
1359
|
+
}
|
|
1360
|
+
function readMarkers(prelude) {
|
|
1361
|
+
const markers = [];
|
|
1362
|
+
const malformed = [];
|
|
1363
|
+
for (const token of tokenize(prelude)) {
|
|
1364
|
+
if (token.type !== "comment" || token.raw.length < 4 || !token.raw.endsWith("*/")) continue;
|
|
1365
|
+
const body = token.raw.slice(2, -2).trim();
|
|
1366
|
+
if (!body.startsWith(MARKER_HEAD)) continue;
|
|
1367
|
+
if (body.startsWith(`${MARKER_HEAD}:`)) {
|
|
1368
|
+
markers.push(parseMarker(body, token.startIndex, token.endIndex));
|
|
1369
|
+
} else {
|
|
1370
|
+
malformed.push({ start: token.startIndex, end: token.endIndex, text: token.raw });
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
return { markers, malformed };
|
|
1374
|
+
}
|
|
1375
|
+
function longhandsCoveredBy(name) {
|
|
1376
|
+
return name.toLowerCase() === "all" ? [] : longhandsOf(name).map((longhand) => standardName(longhand));
|
|
1377
|
+
}
|
|
1378
|
+
function coveredLonghands(markers, laterProperty) {
|
|
1379
|
+
const covered = /* @__PURE__ */ new Set();
|
|
1380
|
+
const isAll = laterProperty.toLowerCase() === "all";
|
|
1381
|
+
for (const marker of markers) {
|
|
1382
|
+
for (const name of marker.names) {
|
|
1383
|
+
if (isAll && name.toLowerCase() === "all") covered.add("*");
|
|
1384
|
+
for (const longhand of longhandsCoveredBy(name)) covered.add(longhand);
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
return covered;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
// src/directive/order-print.ts
|
|
1391
|
+
var MARKER_HEAD2 = "nave-allow-override";
|
|
1392
|
+
var WORD_LIKE = /* @__PURE__ */ new Set([
|
|
1393
|
+
"dimension-token",
|
|
1394
|
+
"function-token",
|
|
1395
|
+
"hash-token",
|
|
1396
|
+
"ident-token",
|
|
1397
|
+
"number-token",
|
|
1398
|
+
"percentage-token",
|
|
1399
|
+
"url-token"
|
|
1400
|
+
]);
|
|
1401
|
+
var OPENING = /* @__PURE__ */ new Set(["(-token", "[-token", "function-token"]);
|
|
1402
|
+
var CLOSING = /* @__PURE__ */ new Set([")-token", "]-token", "comma-token", "semicolon-token"]);
|
|
1403
|
+
function isSpaced(gap, previous, next) {
|
|
1404
|
+
if (!gap.hasComment) return gap.hasWhitespace;
|
|
1405
|
+
if (CLOSING.has(next.type) || OPENING.has(previous.type)) return false;
|
|
1406
|
+
const isWordBeforeParenthesis = previous.type === "ident-token" && next.type === "(-token";
|
|
1407
|
+
return gap.hasWhitespace || isWordBeforeParenthesis || WORD_LIKE.has(previous.type) && WORD_LIKE.has(next.type);
|
|
1408
|
+
}
|
|
1409
|
+
function printedValue(value) {
|
|
1410
|
+
let printed = "";
|
|
1411
|
+
let previous;
|
|
1412
|
+
let gap = { hasComment: false, hasWhitespace: false };
|
|
1413
|
+
for (const token of tokenize(value)) {
|
|
1414
|
+
if (token.type === "whitespace-token") {
|
|
1415
|
+
gap = { ...gap, hasWhitespace: true };
|
|
1416
|
+
} else if (token.type === "comment") {
|
|
1417
|
+
gap = { ...gap, hasComment: true };
|
|
1418
|
+
} else {
|
|
1419
|
+
if (previous !== void 0 && isSpaced(gap, previous, token)) printed += " ";
|
|
1420
|
+
printed += token.raw;
|
|
1421
|
+
previous = token;
|
|
1422
|
+
gap = { hasComment: false, hasWhitespace: false };
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
return printed;
|
|
1426
|
+
}
|
|
1427
|
+
function directiveText(prelude) {
|
|
1428
|
+
return `@nave ${prelude.trim()};`;
|
|
1429
|
+
}
|
|
1430
|
+
function withAtomsInOrder(prelude, atoms2, order) {
|
|
1431
|
+
let result = "";
|
|
1432
|
+
let cursor = 0;
|
|
1433
|
+
for (const [slot, atom] of atoms2.entries()) {
|
|
1434
|
+
result += prelude.slice(cursor, atom.offset) + atoms2[order[slot]].name;
|
|
1435
|
+
cursor = atom.endOffset;
|
|
1436
|
+
}
|
|
1437
|
+
return result + prelude.slice(cursor);
|
|
1438
|
+
}
|
|
1439
|
+
function reorderedDirective(prelude, atoms2, placement) {
|
|
1440
|
+
const rest = atoms2.map((_atom, index) => index).filter((index) => !placement.moving.includes(index));
|
|
1441
|
+
const at = rest.indexOf(placement.after);
|
|
1442
|
+
const order = [...rest.slice(0, at + 1), ...placement.moving, ...rest.slice(at + 1)];
|
|
1443
|
+
return directiveText(withAtomsInOrder(prelude, atoms2, order));
|
|
1444
|
+
}
|
|
1445
|
+
function markerComment(names, reason) {
|
|
1446
|
+
const suffix = reason === void 0 ? "" : ` -- ${reason}`;
|
|
1447
|
+
return `/* ${MARKER_HEAD2}: ${names.join(" ")}${suffix} */`;
|
|
1448
|
+
}
|
|
1449
|
+
function withMarker(prelude, additions, found) {
|
|
1450
|
+
const first = found.markers[0];
|
|
1451
|
+
if (first) {
|
|
1452
|
+
const names = [...first.names, ...additions.filter((name) => !first.names.includes(name))];
|
|
1453
|
+
return prelude.slice(0, first.start) + markerComment(names, first.reason) + prelude.slice(first.end);
|
|
1454
|
+
}
|
|
1455
|
+
const bad = found.malformed[0];
|
|
1456
|
+
if (bad) {
|
|
1457
|
+
return prelude.slice(0, bad.start) + markerComment(additions, void 0) + prelude.slice(bad.end);
|
|
1458
|
+
}
|
|
1459
|
+
return `${markerComment(additions, void 0)} ${prelude.trim()}`;
|
|
1460
|
+
}
|
|
1461
|
+
function markedDirective(prelude, additions) {
|
|
1462
|
+
return directiveText(withMarker(prelude, additions, readMarkers(prelude)));
|
|
1463
|
+
}
|
|
1464
|
+
function directiveWithAtomsBefore(prelude, atoms2, placement) {
|
|
1465
|
+
const rest = atoms2.map((_atom, index) => index).filter((index) => !placement.moving.includes(index));
|
|
1466
|
+
const at = rest.indexOf(placement.before);
|
|
1467
|
+
const order = [...rest.slice(0, at), ...placement.moving, ...rest.slice(at)];
|
|
1468
|
+
return directiveText(withAtomsInOrder(prelude, atoms2, order));
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
// src/directive/order-outward-names.ts
|
|
1472
|
+
function nestedText(node) {
|
|
1473
|
+
if (node.kind === "rule") return `the ${printedValue(node.selector)} block`;
|
|
1474
|
+
if (node.kind === "group" || node.kind === "opaque") {
|
|
1475
|
+
return ["the", `@${node.name}`, printedValue(node.prelude), "block"].filter((part) => part !== "").join(" ");
|
|
1476
|
+
}
|
|
1477
|
+
return "";
|
|
1478
|
+
}
|
|
1479
|
+
var SMALL_ORDINALS = [
|
|
1480
|
+
"first",
|
|
1481
|
+
"second",
|
|
1482
|
+
"third",
|
|
1483
|
+
"fourth",
|
|
1484
|
+
"fifth",
|
|
1485
|
+
"sixth",
|
|
1486
|
+
"seventh",
|
|
1487
|
+
"eighth",
|
|
1488
|
+
"ninth",
|
|
1489
|
+
"tenth"
|
|
1490
|
+
];
|
|
1491
|
+
function ordinal(place) {
|
|
1492
|
+
if (place <= SMALL_ORDINALS.length) return SMALL_ORDINALS[place - 1];
|
|
1493
|
+
const lastTwo = place % 100;
|
|
1494
|
+
const last = place % 10;
|
|
1495
|
+
if (lastTwo < 11 || lastTwo > 13) {
|
|
1496
|
+
if (last === 1) return `${place}st`;
|
|
1497
|
+
if (last === 2) return `${place}nd`;
|
|
1498
|
+
if (last === 3) return `${place}rd`;
|
|
1499
|
+
}
|
|
1500
|
+
return `${place}th`;
|
|
1501
|
+
}
|
|
1502
|
+
function bareName(node) {
|
|
1503
|
+
if (node.kind === "rule") return printedValue(node.selector);
|
|
1504
|
+
if (node.kind === "group" || node.kind === "opaque") {
|
|
1505
|
+
return [`@${node.name}`, printedValue(node.prelude)].filter((part) => part !== "@" && part !== "").join(" ");
|
|
1506
|
+
}
|
|
1507
|
+
return void 0;
|
|
1508
|
+
}
|
|
1509
|
+
function namesOf(nodes) {
|
|
1510
|
+
const names = nodes.map((node) => bareName(node));
|
|
1511
|
+
const places = /* @__PURE__ */ new Map();
|
|
1512
|
+
const names2 = /* @__PURE__ */ new Map();
|
|
1513
|
+
for (const [index, node] of nodes.entries()) {
|
|
1514
|
+
const name = names[index];
|
|
1515
|
+
if (name === void 0) continue;
|
|
1516
|
+
const count = names.filter((other) => other === name).length;
|
|
1517
|
+
const place = (places.get(name) ?? 0) + 1;
|
|
1518
|
+
places.set(name, place);
|
|
1519
|
+
names2.set(node.ref, count > 1 ? `the ${ordinal(place)} ${name} block` : `the ${name} block`);
|
|
1520
|
+
}
|
|
1521
|
+
return names2;
|
|
1522
|
+
}
|
|
1523
|
+
function foldInto(selector, place) {
|
|
1524
|
+
const tokens = tokenize(selector);
|
|
1525
|
+
let depth = 0;
|
|
1526
|
+
let isList = false;
|
|
1527
|
+
for (const token of tokenize(place)) {
|
|
1528
|
+
if (token.type === "(-token" || token.type === "function-token") depth += 1;
|
|
1529
|
+
else if (token.type === ")-token") depth -= 1;
|
|
1530
|
+
else if (depth === 0 && token.type === "comma-token") isList = true;
|
|
1531
|
+
}
|
|
1532
|
+
const replacement = isList ? `:is(${place})` : place;
|
|
1533
|
+
return tokens.map((token) => token.type === "delim-token" && token.raw === "&" ? replacement : token.raw).join("");
|
|
1534
|
+
}
|
|
1535
|
+
function placeOf(path, blockSelector) {
|
|
1536
|
+
let place = "&";
|
|
1537
|
+
for (const selector of [...path, blockSelector]) {
|
|
1538
|
+
const printed = printedValue(selector);
|
|
1539
|
+
if (printed !== "&") place = foldInto(printed, place);
|
|
1540
|
+
}
|
|
1541
|
+
return place;
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
// src/directive/order-units.ts
|
|
1545
|
+
var GROUP_NAMES = /* @__PURE__ */ new Set(["container", "media", "supports"]);
|
|
1546
|
+
function unitOf(context, selector, conditions, declarations) {
|
|
1547
|
+
return {
|
|
1548
|
+
atom: context.atom,
|
|
1549
|
+
directive: context.directive,
|
|
1550
|
+
selector,
|
|
1551
|
+
conditions,
|
|
1552
|
+
declarations: declarations.map((declaration) => toOrderDeclaration(declaration)),
|
|
1553
|
+
specificities: nestedSpecificities(selector, context.amp)
|
|
1554
|
+
};
|
|
1555
|
+
}
|
|
1556
|
+
function unitsOfBlock(context, block) {
|
|
1557
|
+
if (block.kind === "pseudo") return [unitOf(context, block.selector, [], block.declarations)];
|
|
1558
|
+
const conditions = [{ name: block.kind, prelude: block.condition }];
|
|
1559
|
+
const units = block.pseudos.map(
|
|
1560
|
+
(pseudo) => unitOf(context, pseudo.selector, conditions, pseudo.declarations)
|
|
1561
|
+
);
|
|
1562
|
+
if (block.declarations.length > 0) {
|
|
1563
|
+
units.unshift(unitOf(context, "&", conditions, block.declarations));
|
|
1564
|
+
}
|
|
1565
|
+
return units;
|
|
1566
|
+
}
|
|
1567
|
+
function candidatesOfUnit(unit, overrider) {
|
|
1568
|
+
return unit.declarations.map((declaration) => ({
|
|
1569
|
+
declaration,
|
|
1570
|
+
overrider,
|
|
1571
|
+
conditions: unit.conditions,
|
|
1572
|
+
specificities: unit.specificities,
|
|
1573
|
+
holderSelector: unit.selector,
|
|
1574
|
+
siblings: unit.declarations
|
|
1575
|
+
}));
|
|
1576
|
+
}
|
|
1577
|
+
function candidatesOfAtomDeclarations(context, declarations) {
|
|
1578
|
+
const unit = { ...unitOf(context, "&", [], declarations), specificities: [context.amp] };
|
|
1579
|
+
const overrider = {
|
|
1580
|
+
atom: context.atom,
|
|
1581
|
+
directive: context.directive,
|
|
1582
|
+
kind: "atom",
|
|
1583
|
+
isBlock: false
|
|
1584
|
+
};
|
|
1585
|
+
return candidatesOfUnit(unit, overrider);
|
|
1586
|
+
}
|
|
1587
|
+
function candidatesOfAtomBlock(context, block) {
|
|
1588
|
+
const overrider = {
|
|
1589
|
+
atom: context.atom,
|
|
1590
|
+
directive: context.directive,
|
|
1591
|
+
kind: "atom",
|
|
1592
|
+
isBlock: true
|
|
1593
|
+
};
|
|
1594
|
+
return unitsOfBlock(context, block).flatMap((unit) => candidatesOfUnit(unit, overrider));
|
|
1595
|
+
}
|
|
1596
|
+
var NO_CONDITIONS = [];
|
|
1597
|
+
function conditionsOf(chain) {
|
|
1598
|
+
if (chain === void 0) return NO_CONDITIONS;
|
|
1599
|
+
if (chain.array === void 0) {
|
|
1600
|
+
const rules = [];
|
|
1601
|
+
for (let link = chain; link; link = link.parent) {
|
|
1602
|
+
rules.push(link.rule);
|
|
1603
|
+
}
|
|
1604
|
+
chain.array = rules.toReversed();
|
|
1605
|
+
}
|
|
1606
|
+
return chain.array;
|
|
1607
|
+
}
|
|
1608
|
+
function levelOf(nodes, walk, isRule) {
|
|
1609
|
+
const read = isRule ? nodes.flatMap((node) => node.kind === "directive" ? walk.emitted(node).nodes : [node]) : nodes;
|
|
1610
|
+
const siblings = read.flatMap(
|
|
1611
|
+
(node) => node.kind === "decl" ? [{ prop: node.prop, value: node.value, important: node.important }] : []
|
|
1612
|
+
);
|
|
1613
|
+
return { next: 0, nodes: read, siblings, walk };
|
|
1614
|
+
}
|
|
1615
|
+
function enter(node, level, found) {
|
|
1616
|
+
const { walk } = level;
|
|
1617
|
+
if (node.kind === "decl") {
|
|
1618
|
+
const { prop, value, important } = node;
|
|
1619
|
+
found.push({
|
|
1620
|
+
declaration: { prop, value, important },
|
|
1621
|
+
overrider: walk.overrider,
|
|
1622
|
+
conditions: conditionsOf(walk.chain),
|
|
1623
|
+
specificities: walk.specificities,
|
|
1624
|
+
holderSelector: walk.holderSelector,
|
|
1625
|
+
siblings: level.siblings
|
|
1626
|
+
});
|
|
1627
|
+
return void 0;
|
|
1628
|
+
}
|
|
1629
|
+
if (node.kind === "rule") {
|
|
1630
|
+
const specificities = walk.specificities.flatMap((s) => nestedSpecificities(node.selector, s));
|
|
1631
|
+
if (specificities.length === 0) return void 0;
|
|
1632
|
+
const holderSelector = node.selector.trim() === "&" ? walk.holderSelector : node.selector;
|
|
1633
|
+
return levelOf(node.nodes, { ...walk, specificities, holderSelector }, true);
|
|
1634
|
+
}
|
|
1635
|
+
if (node.kind === "group" && GROUP_NAMES.has(node.name)) {
|
|
1636
|
+
const chain = { rule: { name: node.name, prelude: node.prelude }, parent: walk.chain };
|
|
1637
|
+
return levelOf(node.nodes, { ...walk, chain }, false);
|
|
1638
|
+
}
|
|
1639
|
+
return void 0;
|
|
1640
|
+
}
|
|
1641
|
+
function walkNodes(nodes, walk, isRule) {
|
|
1642
|
+
const found = [];
|
|
1643
|
+
const stack = [levelOf(nodes, walk, isRule)];
|
|
1644
|
+
while (stack.length > 0) {
|
|
1645
|
+
const level = stack.at(-1);
|
|
1646
|
+
const node = level.nodes[level.next++];
|
|
1647
|
+
if (node === void 0) {
|
|
1648
|
+
stack.pop();
|
|
1649
|
+
continue;
|
|
1650
|
+
}
|
|
1651
|
+
const inner = enter(node, level, found);
|
|
1652
|
+
if (inner !== void 0) stack.push(inner);
|
|
1653
|
+
}
|
|
1654
|
+
return found;
|
|
1655
|
+
}
|
|
1656
|
+
function ownWalk(node, top, emitted, reach) {
|
|
1657
|
+
return {
|
|
1658
|
+
chain: reach.chain,
|
|
1659
|
+
emitted,
|
|
1660
|
+
holderSelector: "&",
|
|
1661
|
+
overrider: { kind: "own", top, topRef: node.ref },
|
|
1662
|
+
specificities: reach.specificities
|
|
1663
|
+
};
|
|
1664
|
+
}
|
|
1665
|
+
function candidatesOfOwnNode(node, amp, emitted, reach) {
|
|
1666
|
+
const from = reach ?? { chain: void 0, specificities: [amp] };
|
|
1667
|
+
if (node.kind === "decl") {
|
|
1668
|
+
return walkNodes([node], ownWalk(node, { kind: "declaration" }, emitted, from), false);
|
|
1669
|
+
}
|
|
1670
|
+
if (node.kind === "rule") {
|
|
1671
|
+
const top = { kind: "rule", selector: node.selector };
|
|
1672
|
+
const specificities = from.specificities.flatMap((s) => nestedSpecificities(node.selector, s));
|
|
1673
|
+
if (specificities.length === 0) return [];
|
|
1674
|
+
const walk = {
|
|
1675
|
+
...ownWalk(node, top, emitted, from),
|
|
1676
|
+
specificities,
|
|
1677
|
+
holderSelector: node.selector
|
|
1678
|
+
};
|
|
1679
|
+
return walkNodes(node.nodes, walk, true);
|
|
1680
|
+
}
|
|
1681
|
+
if (node.kind === "group" && GROUP_NAMES.has(node.name)) {
|
|
1682
|
+
const top = { kind: "group", name: node.name, prelude: node.prelude };
|
|
1683
|
+
const chain = { rule: { name: node.name, prelude: node.prelude }, parent: from.chain };
|
|
1684
|
+
return walkNodes(node.nodes, { ...ownWalk(node, top, emitted, from), chain }, false);
|
|
1685
|
+
}
|
|
1686
|
+
return [];
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
// src/directive/order-outward-search.ts
|
|
1690
|
+
function enter2(node, level) {
|
|
1691
|
+
if (node.kind === "rule") {
|
|
1692
|
+
const specificities = level.specificities.flatMap((s) => nestedSpecificities(node.selector, s));
|
|
1693
|
+
if (specificities.length === 0) return void 0;
|
|
1694
|
+
const path = [...level.path, node.selector];
|
|
1695
|
+
return {
|
|
1696
|
+
...level,
|
|
1697
|
+
next: 0,
|
|
1698
|
+
isGroupOnly: false,
|
|
1699
|
+
isRule: true,
|
|
1700
|
+
nodes: node.nodes,
|
|
1701
|
+
path,
|
|
1702
|
+
ref: node.ref,
|
|
1703
|
+
specificities
|
|
1704
|
+
};
|
|
1705
|
+
}
|
|
1706
|
+
if (node.kind === "group" && GROUP_NAMES.has(node.name)) {
|
|
1707
|
+
const chain = { rule: { name: node.name, prelude: node.prelude }, parent: level.chain };
|
|
1708
|
+
return { ...level, next: 0, chain, isRule: false, nodes: node.nodes, ref: node.ref };
|
|
1709
|
+
}
|
|
1710
|
+
return void 0;
|
|
1711
|
+
}
|
|
1712
|
+
function groupFacts(stack) {
|
|
1713
|
+
return stack.flatMap((level) => {
|
|
1714
|
+
const container = level.nodes[level.next - 1];
|
|
1715
|
+
if (container === void 0 || level.isRule || !level.isGroupOnly) return [];
|
|
1716
|
+
return [
|
|
1717
|
+
{
|
|
1718
|
+
above: namesOf(level.nodes).get(container.ref) ?? "",
|
|
1719
|
+
chain: level.chain,
|
|
1720
|
+
container: container.ref,
|
|
1721
|
+
group: level.ref,
|
|
1722
|
+
later: level.nodes.slice(level.next),
|
|
1723
|
+
names: namesOf(level.nodes),
|
|
1724
|
+
specificities: level.specificities
|
|
1725
|
+
}
|
|
1726
|
+
];
|
|
1727
|
+
});
|
|
1728
|
+
}
|
|
1729
|
+
function directivesBelow(top, amp) {
|
|
1730
|
+
const start = {
|
|
1731
|
+
next: 0,
|
|
1732
|
+
chain: void 0,
|
|
1733
|
+
isGroupOnly: true,
|
|
1734
|
+
isRule: true,
|
|
1735
|
+
nodes: [],
|
|
1736
|
+
path: [],
|
|
1737
|
+
ref: top.ref,
|
|
1738
|
+
specificities: [amp]
|
|
1739
|
+
};
|
|
1740
|
+
const first = enter2(top, start);
|
|
1741
|
+
if (first === void 0) return [];
|
|
1742
|
+
const found = [];
|
|
1743
|
+
const stack = [first];
|
|
1744
|
+
while (stack.length > 0) {
|
|
1745
|
+
const level = stack.at(-1);
|
|
1746
|
+
const node = level.nodes[level.next++];
|
|
1747
|
+
if (node === void 0) {
|
|
1748
|
+
stack.pop();
|
|
1749
|
+
} else if (node.kind === "directive") {
|
|
1750
|
+
if (level.isRule) {
|
|
1751
|
+
found.push({
|
|
1752
|
+
chain: level.chain,
|
|
1753
|
+
directive: node,
|
|
1754
|
+
groups: groupFacts(stack),
|
|
1755
|
+
path: level.path,
|
|
1756
|
+
specificities: level.specificities
|
|
1757
|
+
});
|
|
1758
|
+
}
|
|
1759
|
+
} else {
|
|
1760
|
+
const inner = enter2(node, level);
|
|
1761
|
+
if (inner !== void 0) stack.push(inner);
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
return found;
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
// src/directive/order-where.ts
|
|
1768
|
+
var IMPLIED_STATES = /* @__PURE__ */ new Map([
|
|
1769
|
+
[":focus", [":focus-within"]],
|
|
1770
|
+
[":focus-visible", [":focus", ":focus-within"]]
|
|
1771
|
+
]);
|
|
1772
|
+
var OPENING2 = /* @__PURE__ */ new Set(["(-token", "[-token", "function-token"]);
|
|
1773
|
+
var CLOSING2 = /* @__PURE__ */ new Set([")-token", "]-token"]);
|
|
1774
|
+
function isCodeChar(scan, text, i) {
|
|
1775
|
+
const char = text[i];
|
|
1776
|
+
if (scan.quote) {
|
|
1777
|
+
if (char === scan.quote && text[i - 1] !== "\\") scan.quote = void 0;
|
|
1778
|
+
return false;
|
|
1779
|
+
}
|
|
1780
|
+
if (char === '"' || char === "'") {
|
|
1781
|
+
scan.quote = char;
|
|
1782
|
+
return false;
|
|
1783
|
+
}
|
|
1784
|
+
if ("([".includes(char)) scan.depth++;
|
|
1785
|
+
else if (")]".includes(char)) scan.depth--;
|
|
1786
|
+
return true;
|
|
1787
|
+
}
|
|
1788
|
+
function isPartStart(text, i) {
|
|
1789
|
+
return ".#[:".includes(text[i]) && text[i - 1] !== ":";
|
|
1790
|
+
}
|
|
1791
|
+
function compoundParts(selector) {
|
|
1792
|
+
const text = selector.trim();
|
|
1793
|
+
if (!text.startsWith("&")) return void 0;
|
|
1794
|
+
const parts = [];
|
|
1795
|
+
const scan = { depth: 0, quote: void 0 };
|
|
1796
|
+
for (let i = 1; i < text.length; i++) {
|
|
1797
|
+
const isTopLevel = scan.depth === 0 && scan.quote === void 0;
|
|
1798
|
+
const isCode = isCodeChar(scan, text, i);
|
|
1799
|
+
const isSeparator = isTopLevel && isCode && /[\s,>+~&]/.test(text[i]);
|
|
1800
|
+
if (isSeparator || !isCharAppended(parts, text, i, isTopLevel && isCode)) return void 0;
|
|
1801
|
+
}
|
|
1802
|
+
return parts;
|
|
1803
|
+
}
|
|
1804
|
+
function isCharAppended(parts, text, i, isCodeAtTop) {
|
|
1805
|
+
if (isCodeAtTop && isPartStart(text, i)) parts.push("");
|
|
1806
|
+
const current = parts.pop();
|
|
1807
|
+
if (current === void 0) return false;
|
|
1808
|
+
parts.push(current + text[i]);
|
|
1809
|
+
return true;
|
|
1810
|
+
}
|
|
1811
|
+
function isOr(token) {
|
|
1812
|
+
return token.type === "ident-token" && String(token.structured?.value).toLowerCase() === "or";
|
|
1813
|
+
}
|
|
1814
|
+
function isListOrDisjunction(prelude) {
|
|
1815
|
+
let depth = 0;
|
|
1816
|
+
for (const token of tokenize(prelude)) {
|
|
1817
|
+
if (OPENING2.has(token.type)) depth += 1;
|
|
1818
|
+
else if (CLOSING2.has(token.type)) depth -= 1;
|
|
1819
|
+
else if (depth === 0 && (token.type === "comma-token" || isOr(token))) return true;
|
|
1820
|
+
}
|
|
1821
|
+
return false;
|
|
1822
|
+
}
|
|
1823
|
+
function conditionText(condition) {
|
|
1824
|
+
const text = `@${condition.name} ${printedValue(condition.prelude)}`;
|
|
1825
|
+
return isListOrDisjunction(condition.prelude) ? `(${text})` : text;
|
|
1826
|
+
}
|
|
1827
|
+
function isTightAfter(token) {
|
|
1828
|
+
return token.type === ")-token" || token.type === "colon-token" || token.type === "comma-token" || token.type === "delim-token" && "<>=".includes(token.raw);
|
|
1829
|
+
}
|
|
1830
|
+
function isTightBefore(token) {
|
|
1831
|
+
return token.type === "(-token" || token.type === "function-token" || token.type === "colon-token" || token.type === "comma-token" || token.type === "delim-token" && "<>=".includes(token.raw);
|
|
1832
|
+
}
|
|
1833
|
+
function conditionKey(condition) {
|
|
1834
|
+
let key = `${condition.name} `;
|
|
1835
|
+
let previous;
|
|
1836
|
+
let hasGap = false;
|
|
1837
|
+
for (const token of tokenize(condition.prelude)) {
|
|
1838
|
+
if (token.type === "whitespace-token" || token.type === "comment") {
|
|
1839
|
+
hasGap = true;
|
|
1840
|
+
continue;
|
|
1841
|
+
}
|
|
1842
|
+
const isSpaced2 = previous !== void 0 && hasGap && !isTightBefore(previous) && !isTightAfter(token);
|
|
1843
|
+
key += isSpaced2 ? ` ${token.raw}` : token.raw;
|
|
1844
|
+
previous = token;
|
|
1845
|
+
hasGap = false;
|
|
1846
|
+
}
|
|
1847
|
+
return key;
|
|
1848
|
+
}
|
|
1849
|
+
function phrase(onText, conditions) {
|
|
1850
|
+
const on = onText === void 0 || onText === "" ? [] : [`on ${onText}`];
|
|
1851
|
+
const under = conditions.length === 0 ? [] : [`under ${conditions.map((c) => conditionText(c)).join(" and ")}`];
|
|
1852
|
+
return [...on, ...under].join(" ");
|
|
1853
|
+
}
|
|
1854
|
+
function statesOf(selector) {
|
|
1855
|
+
return compoundParts(selector) ?? [];
|
|
1856
|
+
}
|
|
1857
|
+
function whereOf(selector, conditions) {
|
|
1858
|
+
const printed = printedValue(selector);
|
|
1859
|
+
const parts = compoundParts(printed);
|
|
1860
|
+
return phrase(parts === void 0 ? printed : parts.join(""), conditions);
|
|
1861
|
+
}
|
|
1862
|
+
function isSaid(part, said) {
|
|
1863
|
+
const lower = part.toLowerCase();
|
|
1864
|
+
return said.some(
|
|
1865
|
+
(s) => s.toLowerCase() === lower || (IMPLIED_STATES.get(s.toLowerCase()) ?? []).includes(lower)
|
|
1866
|
+
);
|
|
1867
|
+
}
|
|
1868
|
+
function alsoWhere(first, later) {
|
|
1869
|
+
const firstParts = first.said ?? compoundParts(printedValue(first.selector)) ?? [];
|
|
1870
|
+
const laterSelector = printedValue(later.selector);
|
|
1871
|
+
const laterParts = compoundParts(laterSelector);
|
|
1872
|
+
const seen = new Set(first.conditions.map((c) => conditionKey(c)));
|
|
1873
|
+
const conditions = later.conditions.filter((c) => !seen.has(conditionKey(c)));
|
|
1874
|
+
if (laterParts === void 0) return phrase(laterSelector, conditions);
|
|
1875
|
+
return phrase(laterParts.filter((part) => !isSaid(part, firstParts)).join(""), conditions);
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
// src/directive/rule-emit.ts
|
|
1879
|
+
function directiveFacts(node, result) {
|
|
1880
|
+
return {
|
|
1881
|
+
ref: node.ref,
|
|
1882
|
+
prelude: node.prelude,
|
|
1883
|
+
atoms: result.atoms.map((atom, atomIndex) => ({
|
|
1884
|
+
atomIndex,
|
|
1885
|
+
name: atom.name,
|
|
1886
|
+
offset: atom.offset,
|
|
1887
|
+
endOffset: atom.endOffset
|
|
1888
|
+
}))
|
|
1889
|
+
};
|
|
1890
|
+
}
|
|
1891
|
+
function recordDropped(state, directive, atoms2) {
|
|
1892
|
+
const named = atoms2.flatMap(
|
|
1893
|
+
(planned, index) => planned.blocks.length === 0 ? [] : [
|
|
1894
|
+
{
|
|
1895
|
+
atom: directive.atoms[index],
|
|
1896
|
+
declarations: planned.declarations,
|
|
1897
|
+
wheres: planned.blocks.map((block) => blockWhere(block))
|
|
1898
|
+
}
|
|
1899
|
+
]
|
|
1900
|
+
);
|
|
1901
|
+
if (named.length > 0) state.dropped.push({ directive, atoms: named });
|
|
1902
|
+
}
|
|
1903
|
+
function recordSegments(state, directive, atoms2) {
|
|
1904
|
+
if (state.isPseudoElementRule) recordDropped(state, directive, atoms2);
|
|
1905
|
+
for (const [atomIndex, planned] of atoms2.entries()) {
|
|
1906
|
+
const atom = directive.atoms[atomIndex];
|
|
1907
|
+
if (planned.declarations.length > 0) {
|
|
1908
|
+
state.segments.push({
|
|
1909
|
+
kind: "atom-declarations",
|
|
1910
|
+
directive,
|
|
1911
|
+
atom,
|
|
1912
|
+
declarations: planned.declarations
|
|
1913
|
+
});
|
|
1914
|
+
}
|
|
1915
|
+
if (state.isPseudoElementRule) continue;
|
|
1916
|
+
for (const block of planned.blocks) {
|
|
1917
|
+
state.segments.push({ kind: "atom-block", directive, atom, block });
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
function blockWhere(block) {
|
|
1922
|
+
if (block.kind === "pseudo") return whereOf(block.selector, []);
|
|
1923
|
+
return whereOf("&", [{ name: block.kind, prelude: block.condition }]);
|
|
1924
|
+
}
|
|
1925
|
+
function firstAtomWithBlock(walk) {
|
|
1926
|
+
const index = walk.atoms.findIndex((atom) => atom.blocks.length > 0);
|
|
1927
|
+
return index === -1 ? void 0 : walk.directive.atoms[index];
|
|
1928
|
+
}
|
|
1929
|
+
function recordRun(state, walk) {
|
|
1930
|
+
const { directive, follows, pending } = walk;
|
|
1931
|
+
const nested = state.lastNested ?? { text: "" };
|
|
1932
|
+
const hasBlockOfOwn = pending.atoms.some((atom) => walk.atoms[atom.atomIndex].blocks.length > 0);
|
|
1933
|
+
state.runs.push({
|
|
1934
|
+
kind: "directive",
|
|
1935
|
+
above: state.above ?? "",
|
|
1936
|
+
atoms: [...pending.atoms],
|
|
1937
|
+
canMoveDirective: !state.ownDeclarationSinceAbove,
|
|
1938
|
+
canReorder: follows !== void 0 && !walk.isNestedBefore && firstAtomWithBlock(walk)?.atomIndex === follows.atom.atomIndex && !hasBlockOfOwn,
|
|
1939
|
+
directive,
|
|
1940
|
+
follows,
|
|
1941
|
+
isWrappedBefore: state.hasOwnNested,
|
|
1942
|
+
nested
|
|
1943
|
+
});
|
|
1944
|
+
}
|
|
1945
|
+
function flushDeclarations(state, walk) {
|
|
1946
|
+
const { declarations } = walk.pending;
|
|
1947
|
+
if (declarations.length === 0) return;
|
|
1948
|
+
const isWrapped = state.isNested && !state.isPseudoElementRule;
|
|
1949
|
+
walk.emissions.push({ kind: "declarations", declarations: [...declarations], isWrapped });
|
|
1950
|
+
if (isWrapped) recordRun(state, walk);
|
|
1951
|
+
walk.pending.declarations = [];
|
|
1952
|
+
walk.pending.atoms = [];
|
|
1953
|
+
}
|
|
1954
|
+
function noteAbove(state, walk) {
|
|
1955
|
+
if (state.above !== void 0) return;
|
|
1956
|
+
const first = firstAtomWithBlock(walk);
|
|
1957
|
+
state.above = state.directiveTotal === 1 ? "the directive" : `the directive that names "${first.name}"`;
|
|
1958
|
+
}
|
|
1959
|
+
function emitAtom(state, walk, index) {
|
|
1960
|
+
const planned = walk.atoms[index];
|
|
1961
|
+
const atom = walk.directive.atoms[index];
|
|
1962
|
+
if (planned.declarations.length > 0) {
|
|
1963
|
+
walk.pending.declarations.push(...planned.declarations);
|
|
1964
|
+
walk.pending.atoms.push(atom);
|
|
1965
|
+
}
|
|
1966
|
+
if (planned.blocks.length === 0 || state.isPseudoElementRule) return;
|
|
1967
|
+
flushDeclarations(state, walk);
|
|
1968
|
+
for (const block of planned.blocks) walk.emissions.push({ kind: "block", block });
|
|
1969
|
+
noteAbove(state, walk);
|
|
1970
|
+
const last = planned.blocks.at(-1);
|
|
1971
|
+
walk.follows = { atom, where: blockWhere(last) };
|
|
1972
|
+
state.lastNested = {
|
|
1973
|
+
text: `the block of "${atom.name}" ${blockWhere(last)}`,
|
|
1974
|
+
block: { atom, directive: walk.directive }
|
|
1975
|
+
};
|
|
1976
|
+
state.isNested = true;
|
|
1977
|
+
}
|
|
1978
|
+
function emitAtoms(state, directive, atoms2) {
|
|
1979
|
+
const walk = {
|
|
1980
|
+
atoms: atoms2,
|
|
1981
|
+
directive,
|
|
1982
|
+
emissions: [],
|
|
1983
|
+
pending: { atoms: [], declarations: [] },
|
|
1984
|
+
isNestedBefore: state.isNested,
|
|
1985
|
+
follows: void 0
|
|
1986
|
+
};
|
|
1987
|
+
for (const index of atoms2.keys()) emitAtom(state, walk, index);
|
|
1988
|
+
flushDeclarations(state, walk);
|
|
1989
|
+
return walk.emissions;
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1992
|
+
// src/directive/order-outward.ts
|
|
1993
|
+
function isSameCondition(a, b) {
|
|
1994
|
+
return conditionKey(a) === conditionKey(b);
|
|
1995
|
+
}
|
|
1996
|
+
function unitsOfBlock2(found, context, block) {
|
|
1997
|
+
const make = (selector, conditions2, declarations) => ({
|
|
1998
|
+
...context,
|
|
1999
|
+
selector,
|
|
2000
|
+
placeSelector: placeOf(found.path, selector),
|
|
2001
|
+
placeStates: [...found.path, selector].flatMap((part) => statesOf(printedValue(part))),
|
|
2002
|
+
conditions: conditions2,
|
|
2003
|
+
declarations: declarations.map((declaration) => toOrderDeclaration(declaration)),
|
|
2004
|
+
specificities: found.specificities.flatMap((s) => nestedSpecificities(selector, s))
|
|
2005
|
+
});
|
|
2006
|
+
const path = conditionsOf(found.chain);
|
|
2007
|
+
if (block.kind === "pseudo") return [make(block.selector, path, block.declarations)];
|
|
2008
|
+
const own = { name: block.kind, prelude: block.condition };
|
|
2009
|
+
const conditions = path.some((condition) => isSameCondition(condition, own)) ? path : [own, ...path];
|
|
2010
|
+
const units = block.pseudos.map(
|
|
2011
|
+
(pseudo) => make(pseudo.selector, conditions, pseudo.declarations)
|
|
2012
|
+
);
|
|
2013
|
+
if (block.declarations.length > 0) units.unshift(make("&", conditions, block.declarations));
|
|
2014
|
+
return units;
|
|
2015
|
+
}
|
|
2016
|
+
function outwardOf(finding, how) {
|
|
2017
|
+
const { overrider } = finding.candidate;
|
|
2018
|
+
const name = overrider.kind === "own" ? how.names.get(overrider.topRef) : void 0;
|
|
2019
|
+
const { above, level, top } = how;
|
|
2020
|
+
return { ...finding, outward: { above, overrider: name, top, ...level && { level } } };
|
|
2021
|
+
}
|
|
2022
|
+
function pairs(units, candidates, how) {
|
|
2023
|
+
return units.flatMap(
|
|
2024
|
+
(unit) => candidates.flatMap((candidate) => {
|
|
2025
|
+
const finding = compare(unit, candidate);
|
|
2026
|
+
return finding === void 0 ? [] : [outwardOf(finding, how)];
|
|
2027
|
+
})
|
|
2028
|
+
);
|
|
2029
|
+
}
|
|
2030
|
+
function groupCandidates(group, enclosing) {
|
|
2031
|
+
const reach = { chain: group.chain, specificities: group.specificities };
|
|
2032
|
+
const { levels } = enclosing;
|
|
2033
|
+
const nodes = typeof levels === "object" && group.container !== levels.child ? group.later.filter((node) => node.ref === levels.child) : group.later;
|
|
2034
|
+
return nodes.flatMap((node) => candidatesOfOwnNode(node, enclosing.amp, enclosing.emitted, reach));
|
|
2035
|
+
}
|
|
2036
|
+
function findingsBelow(enclosing) {
|
|
2037
|
+
const { amp, emitted, top } = enclosing;
|
|
2038
|
+
const above = enclosing.names.get(top.ref) ?? nestedText(top);
|
|
2039
|
+
return directivesBelow(top, amp).flatMap((found) => {
|
|
2040
|
+
const { atoms: atoms2 } = emitted(found.directive);
|
|
2041
|
+
const facts = directiveFacts(found.directive, { atoms: atoms2});
|
|
2042
|
+
const own = {
|
|
2043
|
+
candidates: enclosing.later,
|
|
2044
|
+
how: { above, names: enclosing.names, top: top.ref }
|
|
2045
|
+
};
|
|
2046
|
+
const groupLevels = enclosing.levels === "enclosing" ? [] : found.groups;
|
|
2047
|
+
const levels = [
|
|
2048
|
+
...typeof enclosing.levels === "object" ? [] : [own],
|
|
2049
|
+
...groupLevels.map((group) => ({
|
|
2050
|
+
candidates: groupCandidates(group, enclosing),
|
|
2051
|
+
how: {
|
|
2052
|
+
above: group.above,
|
|
2053
|
+
level: { container: group.container, group: group.group },
|
|
2054
|
+
names: group.names,
|
|
2055
|
+
top: top.ref
|
|
2056
|
+
}
|
|
2057
|
+
}))
|
|
2058
|
+
];
|
|
2059
|
+
return atoms2.flatMap(
|
|
2060
|
+
(atom, index) => atom.blocks.flatMap(
|
|
2061
|
+
(block) => unitsOfBlock2(found, { atom: facts.atoms[index], directive: facts }, block)
|
|
2062
|
+
).flatMap((unit) => levels.flatMap((level) => pairs([unit], level.candidates, level.how)))
|
|
2063
|
+
);
|
|
2064
|
+
});
|
|
2065
|
+
}
|
|
2066
|
+
function readOf(segment, scope) {
|
|
2067
|
+
if (scope === void 0) return { levels: "all" };
|
|
2068
|
+
if (scope.kind === "child") {
|
|
2069
|
+
return segment === scope.top ? { levels: { child: scope.child } } : void 0;
|
|
2070
|
+
}
|
|
2071
|
+
return scope.segments.has(segment) ? { levels: "all" } : { levels: "enclosing", only: scope.segments };
|
|
2072
|
+
}
|
|
2073
|
+
function outwardFindings(segments, rule, candidatesOfSegment) {
|
|
2074
|
+
const { amp, emitted, scope } = rule;
|
|
2075
|
+
const names = namesOf(
|
|
2076
|
+
segments.flatMap((segment) => segment.kind === "own" ? [segment.node] : [])
|
|
2077
|
+
);
|
|
2078
|
+
return segments.flatMap((segment, index) => {
|
|
2079
|
+
if (segment.kind !== "own") return [];
|
|
2080
|
+
const top = segment.node;
|
|
2081
|
+
if (top.kind !== "rule" && top.kind !== "group") return [];
|
|
2082
|
+
const read = readOf(segment, scope);
|
|
2083
|
+
if (read === void 0) return [];
|
|
2084
|
+
const isCounted = (other) => read.only === void 0 || read.only.has(other);
|
|
2085
|
+
const later = typeof read.levels === "object" ? [] : segments.flatMap(
|
|
2086
|
+
(other, at) => at > index && isCounted(other) ? candidatesOfSegment(at) : []
|
|
2087
|
+
);
|
|
2088
|
+
if (later.length === 0 && (top.kind === "rule" || read.levels === "enclosing")) return [];
|
|
2089
|
+
return findingsBelow({ amp, emitted, later, levels: read.levels, names, top });
|
|
2090
|
+
});
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
// src/directive/order-check.ts
|
|
2094
|
+
function contextOf(segment, amp) {
|
|
2095
|
+
return { amp, atom: segment.atom, directive: segment.directive };
|
|
2096
|
+
}
|
|
2097
|
+
function candidatesOf(segment, amp, emitted) {
|
|
2098
|
+
if (segment.kind === "own") return candidatesOfOwnNode(segment.node, amp, emitted);
|
|
2099
|
+
const context = contextOf(segment, amp);
|
|
2100
|
+
if (segment.kind === "atom-declarations") {
|
|
2101
|
+
return candidatesOfAtomDeclarations(context, segment.declarations);
|
|
2102
|
+
}
|
|
2103
|
+
return candidatesOfAtomBlock(context, segment.block);
|
|
2104
|
+
}
|
|
2105
|
+
function isSameAtom(a, b) {
|
|
2106
|
+
return a.kind !== "own" && b.kind !== "own" && a.directive.ref === b.directive.ref && a.atom.atomIndex === b.atom.atomIndex;
|
|
2107
|
+
}
|
|
2108
|
+
function findingsOfBlock(index, segments, rule, candidatesOfSegment) {
|
|
2109
|
+
const { amp, moved } = rule;
|
|
2110
|
+
const segment = segments[index];
|
|
2111
|
+
const isRead = (other) => moved === void 0 || moved.has(segment) || moved.has(other);
|
|
2112
|
+
const candidates = segments.flatMap(
|
|
2113
|
+
(other, at) => at > index && !isSameAtom(segment, other) && isRead(other) ? candidatesOfSegment(at) : []
|
|
2114
|
+
);
|
|
2115
|
+
if (candidates.length === 0) return [];
|
|
2116
|
+
const units = unitsOfBlock(contextOf(segment, amp), segment.block);
|
|
2117
|
+
return candidates.flatMap(
|
|
2118
|
+
(candidate) => units.map((unit) => compare(unit, candidate)).filter((f) => f !== void 0)
|
|
2119
|
+
);
|
|
2120
|
+
}
|
|
2121
|
+
function pairsIn(segments, rule, candidatesOfPart) {
|
|
2122
|
+
const { amp, emitted, isPseudoElementRule, scope } = rule;
|
|
2123
|
+
const candidatesOfSegment = (index) => candidatesOfPart(segments[index]);
|
|
2124
|
+
const moved = scope?.kind === "moved" ? scope.segments : void 0;
|
|
2125
|
+
const inner = scope?.kind === "child" ? [] : segments.flatMap(
|
|
2126
|
+
(segment, index) => segment.kind === "atom-block" ? findingsOfBlock(index, segments, { amp, moved }, candidatesOfSegment) : []
|
|
2127
|
+
);
|
|
2128
|
+
if (isPseudoElementRule) return inner;
|
|
2129
|
+
return [...inner, ...outwardFindings(segments, { amp, emitted, scope }, candidatesOfSegment)];
|
|
2130
|
+
}
|
|
2131
|
+
function canHoldPair(segments) {
|
|
2132
|
+
return segments.some(
|
|
2133
|
+
(segment) => segment.kind === "atom-block" || segment.kind === "own" && (segment.node.kind === "rule" || segment.node.kind === "group")
|
|
2134
|
+
);
|
|
2135
|
+
}
|
|
2136
|
+
function checkOrder(segments, amp, emitted, isPseudoElementRule = false) {
|
|
2137
|
+
const rule = { amp, emitted, isPseudoElementRule };
|
|
2138
|
+
const known = /* @__PURE__ */ new WeakMap();
|
|
2139
|
+
const candidatesOfPart = (segment) => {
|
|
2140
|
+
let candidates = known.get(segment);
|
|
2141
|
+
if (candidates === void 0) {
|
|
2142
|
+
candidates = candidatesOf(segment, amp, emitted);
|
|
2143
|
+
known.set(segment, candidates);
|
|
2144
|
+
}
|
|
2145
|
+
return candidates;
|
|
2146
|
+
};
|
|
2147
|
+
const findings = pairsIn(segments, rule, candidatesOfPart);
|
|
2148
|
+
return markMoves(
|
|
2149
|
+
findings,
|
|
2150
|
+
segments,
|
|
2151
|
+
(arranged, scope) => pairsIn(arranged, { ...rule, scope }, candidatesOfPart)
|
|
2152
|
+
);
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
// src/selector-utils.ts
|
|
2156
|
+
function isCommentClose(text, index, commentStart) {
|
|
2157
|
+
return text[index] === "/" && text[index - 1] === "*" && index - 1 >= commentStart + 2;
|
|
2158
|
+
}
|
|
2159
|
+
function isConsumedAsLiteral(state, text, index) {
|
|
2160
|
+
if (state.commentStart !== void 0) {
|
|
2161
|
+
if (isCommentClose(text, index, state.commentStart)) state.commentStart = void 0;
|
|
2162
|
+
return true;
|
|
2163
|
+
}
|
|
2164
|
+
if (state.isEscaped) {
|
|
2165
|
+
state.isEscaped = false;
|
|
2166
|
+
return true;
|
|
2167
|
+
}
|
|
2168
|
+
if (text[index] === "\\") {
|
|
2169
|
+
state.isEscaped = true;
|
|
2170
|
+
return true;
|
|
2171
|
+
}
|
|
2172
|
+
if (!state.quote) return false;
|
|
2173
|
+
if (text[index] === state.quote) state.quote = void 0;
|
|
2174
|
+
return true;
|
|
2175
|
+
}
|
|
2176
|
+
function isCodeChar2(state, text, index) {
|
|
2177
|
+
if (isConsumedAsLiteral(state, text, index)) return false;
|
|
2178
|
+
const char = text[index];
|
|
2179
|
+
if (char === '"' || char === "'") {
|
|
2180
|
+
state.quote = char;
|
|
2181
|
+
return false;
|
|
2182
|
+
}
|
|
2183
|
+
if (char === "/" && text[index + 1] === "*") {
|
|
2184
|
+
state.commentStart = index;
|
|
2185
|
+
return false;
|
|
2186
|
+
}
|
|
2187
|
+
return true;
|
|
2188
|
+
}
|
|
2189
|
+
function codeMask(text) {
|
|
2190
|
+
const state = { quote: void 0, isEscaped: false, commentStart: void 0 };
|
|
2191
|
+
return Array.from({ length: text.length }, (_, index) => isCodeChar2(state, text, index));
|
|
2192
|
+
}
|
|
2193
|
+
function splitTopLevel(selectorList) {
|
|
2194
|
+
const mask = codeMask(selectorList);
|
|
2195
|
+
const branches = [];
|
|
2196
|
+
let depth = 0;
|
|
2197
|
+
let start = 0;
|
|
2198
|
+
for (const [index, isCode] of mask.entries()) {
|
|
2199
|
+
if (!isCode) continue;
|
|
2200
|
+
const char = selectorList[index];
|
|
2201
|
+
if (char === "(" || char === "[") depth += 1;
|
|
2202
|
+
else if (char === ")" || char === "]") depth -= 1;
|
|
2203
|
+
else if (char === "," && depth === 0) {
|
|
2204
|
+
branches.push(selectorList.slice(start, index));
|
|
2205
|
+
start = index + 1;
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
return [...branches, selectorList.slice(start)];
|
|
2209
|
+
}
|
|
2210
|
+
function hasNestingSelector(branch) {
|
|
2211
|
+
return codeMask(branch).some((isCode, index) => isCode && branch[index] === "&");
|
|
2212
|
+
}
|
|
2213
|
+
function anchorSelectorList(selectorList) {
|
|
2214
|
+
return splitTopLevel(selectorList).map((branch) => {
|
|
2215
|
+
const trimmed = branch.trim();
|
|
2216
|
+
if (trimmed === "") {
|
|
2217
|
+
throw new Error(
|
|
2218
|
+
`anchorSelectorList: empty selector branch in pseudo key "${selectorList}". Remove the stray or trailing comma: an empty branch would otherwise compile to a bare "&", matching the atom unconditionally.`
|
|
2219
|
+
);
|
|
2220
|
+
}
|
|
2221
|
+
return hasNestingSelector(trimmed) ? trimmed : `&${trimmed}`;
|
|
2222
|
+
}).join(", ");
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
// src/directive/prelude-components.ts
|
|
2226
|
+
var OPENERS3 = /* @__PURE__ */ new Set(["(-token", "[-token", "function-token", "{-token"]);
|
|
2227
|
+
var CLOSERS2 = /* @__PURE__ */ new Set([")-token", "]-token", "}-token"]);
|
|
2228
|
+
function findGroupEnd(tokens, start) {
|
|
2229
|
+
let depth = 1;
|
|
2230
|
+
let i = start + 1;
|
|
2231
|
+
while (i < tokens.length && depth > 0) {
|
|
2232
|
+
if (OPENERS3.has(tokens[i].type)) depth++;
|
|
2233
|
+
else if (CLOSERS2.has(tokens[i].type)) depth--;
|
|
2234
|
+
i++;
|
|
2235
|
+
}
|
|
2236
|
+
return i;
|
|
2237
|
+
}
|
|
2238
|
+
function readGroup(tokens, start, prelude) {
|
|
2239
|
+
const end = findGroupEnd(tokens, start);
|
|
2240
|
+
const last = tokens[end - 1] ?? tokens[start];
|
|
2241
|
+
return {
|
|
2242
|
+
kind: "bad-token",
|
|
2243
|
+
text: prelude.slice(tokens[start].startIndex, last.endIndex),
|
|
2244
|
+
offset: tokens[start].startIndex,
|
|
2245
|
+
endOffset: last.endIndex
|
|
2246
|
+
};
|
|
2247
|
+
}
|
|
2248
|
+
function isBangIdent(tokens, i) {
|
|
2249
|
+
const t = tokens[i];
|
|
2250
|
+
return t.type === "delim-token" && t.structured?.value === "!" && tokens[i + 1]?.type === "ident-token";
|
|
2251
|
+
}
|
|
2252
|
+
function readBangIdent(tokens, i) {
|
|
2253
|
+
const bang = tokens[i];
|
|
2254
|
+
const ident = tokens[i + 1];
|
|
2255
|
+
return {
|
|
2256
|
+
kind: "bad-token",
|
|
2257
|
+
text: bang.raw + ident.raw,
|
|
2258
|
+
offset: bang.startIndex,
|
|
2259
|
+
endOffset: ident.endIndex
|
|
2260
|
+
};
|
|
2261
|
+
}
|
|
2262
|
+
function readSingleToken(t) {
|
|
2263
|
+
if (t.type === "ident-token") {
|
|
2264
|
+
return {
|
|
2265
|
+
kind: "ident",
|
|
2266
|
+
name: t.structured?.value,
|
|
2267
|
+
offset: t.startIndex,
|
|
2268
|
+
endOffset: t.endIndex
|
|
2269
|
+
};
|
|
2270
|
+
}
|
|
2271
|
+
return { kind: "bad-token", text: t.raw, offset: t.startIndex, endOffset: t.endIndex };
|
|
2272
|
+
}
|
|
2273
|
+
function readPreludeComponents(prelude) {
|
|
2274
|
+
const tokens = tokenize(prelude).filter(
|
|
2275
|
+
(t) => t.type !== "whitespace-token" && t.type !== "comment"
|
|
2276
|
+
);
|
|
2277
|
+
const components = [];
|
|
2278
|
+
let i = 0;
|
|
2279
|
+
while (i < tokens.length) {
|
|
2280
|
+
if (OPENERS3.has(tokens[i].type)) {
|
|
2281
|
+
components.push(readGroup(tokens, i, prelude));
|
|
2282
|
+
i = findGroupEnd(tokens, i);
|
|
2283
|
+
continue;
|
|
2284
|
+
}
|
|
2285
|
+
if (isBangIdent(tokens, i)) {
|
|
2286
|
+
components.push(readBangIdent(tokens, i));
|
|
2287
|
+
i += 2;
|
|
2288
|
+
continue;
|
|
2289
|
+
}
|
|
2290
|
+
components.push(readSingleToken(tokens[i]));
|
|
2291
|
+
i++;
|
|
2292
|
+
}
|
|
2293
|
+
return components;
|
|
2294
|
+
}
|
|
2295
|
+
|
|
2296
|
+
// src/directive/plain-object.ts
|
|
2297
|
+
var BOXES = [
|
|
2298
|
+
["String", String.prototype],
|
|
2299
|
+
["Number", Number.prototype],
|
|
2300
|
+
["Boolean", Boolean.prototype],
|
|
2301
|
+
["BigInt", BigInt.prototype],
|
|
2302
|
+
["Symbol", Symbol.prototype]
|
|
2303
|
+
];
|
|
2304
|
+
var utilTypes = globalThis.process?.getBuiltinModule?.("node:util")?.types;
|
|
2305
|
+
function brandByTypes(types, value) {
|
|
2306
|
+
if (types.isStringObject(value)) return "String";
|
|
2307
|
+
if (types.isNumberObject(value)) return "Number";
|
|
2308
|
+
if (types.isBooleanObject(value)) return "Boolean";
|
|
2309
|
+
if (types.isBigIntObject(value)) return "BigInt";
|
|
2310
|
+
return types.isSymbolObject(value) ? "Symbol" : void 0;
|
|
2311
|
+
}
|
|
2312
|
+
function brandByValueOf(value) {
|
|
2313
|
+
for (const [name, prototype] of BOXES) {
|
|
2314
|
+
try {
|
|
2315
|
+
prototype.valueOf.call(value);
|
|
2316
|
+
return name;
|
|
2317
|
+
} catch {
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
return void 0;
|
|
2321
|
+
}
|
|
2322
|
+
function brandOf(value) {
|
|
2323
|
+
return utilTypes === void 0 ? brandByValueOf(value) : brandByTypes(utilTypes, value);
|
|
2324
|
+
}
|
|
2325
|
+
function boxedPrimitiveKind(value) {
|
|
2326
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
2327
|
+
const brand = brandOf(value);
|
|
2328
|
+
if (brand !== void 0) return brand;
|
|
2329
|
+
try {
|
|
2330
|
+
const prototype = Object.getPrototypeOf(value);
|
|
2331
|
+
return BOXES.find(([, box]) => box === prototype)?.[0];
|
|
2332
|
+
} catch {
|
|
2333
|
+
return void 0;
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
function unboxedPrimitive(value) {
|
|
2337
|
+
for (const [, prototype] of BOXES) {
|
|
2338
|
+
try {
|
|
2339
|
+
return prototype.valueOf.call(value);
|
|
2340
|
+
} catch {
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
return void 0;
|
|
2344
|
+
}
|
|
2345
|
+
function isPlainObject(value) {
|
|
2346
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && boxedPrimitiveKind(value) === void 0;
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
// src/directive/resolve.ts
|
|
2350
|
+
function toDeclarations(decls) {
|
|
2351
|
+
return Object.entries(decls).map(([prop, value]) => ({ prop, value }));
|
|
2352
|
+
}
|
|
2353
|
+
function isDeclarationsObject(value) {
|
|
2354
|
+
return isPlainObject(value);
|
|
2355
|
+
}
|
|
2356
|
+
function resolveDeclarations(name, atom) {
|
|
2357
|
+
if (!isDeclarationsObject(atom.declarations)) {
|
|
2358
|
+
throw new Error(`@nave: atom "${name}" is registered without a declarations object`);
|
|
2359
|
+
}
|
|
2360
|
+
return toDeclarations(atom.declarations);
|
|
2361
|
+
}
|
|
2362
|
+
function resolvePseudoBlocks(pseudos) {
|
|
2363
|
+
if (!pseudos) return [];
|
|
2364
|
+
return Object.entries(pseudos).filter(([, decls]) => decls).map(([selector, decls]) => ({
|
|
2365
|
+
kind: "pseudo",
|
|
2366
|
+
selector,
|
|
2367
|
+
declarations: toDeclarations(decls)
|
|
2368
|
+
}));
|
|
2369
|
+
}
|
|
2370
|
+
function resolveConditionalBlocks(kind, blocks) {
|
|
2371
|
+
if (!blocks) return [];
|
|
2372
|
+
const result = [];
|
|
2373
|
+
for (const [condition, block] of Object.entries(blocks)) {
|
|
2374
|
+
if (!block) continue;
|
|
2375
|
+
const declarations = block.declarations ? toDeclarations(block.declarations) : [];
|
|
2376
|
+
const pseudos = resolvePseudoBlocks(block.pseudos);
|
|
2377
|
+
if (declarations.length === 0 && pseudos.length === 0) continue;
|
|
2378
|
+
result.push({ kind, condition, declarations, pseudos });
|
|
2379
|
+
}
|
|
2380
|
+
return result;
|
|
2381
|
+
}
|
|
2382
|
+
function resolveAtom(name, atom) {
|
|
2383
|
+
return {
|
|
2384
|
+
declarations: resolveDeclarations(name, atom),
|
|
2385
|
+
blocks: [
|
|
2386
|
+
...resolvePseudoBlocks(atom.pseudos),
|
|
2387
|
+
...resolveConditionalBlocks("media", atom.media),
|
|
2388
|
+
...resolveConditionalBlocks("container", atom.container)
|
|
2389
|
+
]
|
|
2390
|
+
};
|
|
2391
|
+
}
|
|
2392
|
+
function lookupAtom(name, extend) {
|
|
2393
|
+
if (Object.hasOwn(extend, name)) return extend[name] ?? void 0;
|
|
2394
|
+
if (Object.hasOwn(atoms, name)) return atoms[name];
|
|
2395
|
+
return void 0;
|
|
2396
|
+
}
|
|
2397
|
+
function resolve(names, options = {}) {
|
|
2398
|
+
const extend = options.extend ?? {};
|
|
2399
|
+
const resolved = /* @__PURE__ */ Object.create(null);
|
|
2400
|
+
const unresolved = [];
|
|
2401
|
+
for (const name of names) {
|
|
2402
|
+
const atom = lookupAtom(name, extend);
|
|
2403
|
+
if (!atom) {
|
|
2404
|
+
unresolved.push(name);
|
|
2405
|
+
continue;
|
|
2406
|
+
}
|
|
2407
|
+
resolved[name] = resolveAtom(name, atom);
|
|
2408
|
+
}
|
|
2409
|
+
return { resolved, unresolved };
|
|
2410
|
+
}
|
|
2411
|
+
|
|
2412
|
+
// src/directive/plan.ts
|
|
2413
|
+
function anchorBlock(block) {
|
|
2414
|
+
if (block.kind === "pseudo") {
|
|
2415
|
+
return {
|
|
2416
|
+
kind: "pseudo",
|
|
2417
|
+
selector: anchorSelectorList(block.selector),
|
|
2418
|
+
declarations: block.declarations
|
|
2419
|
+
};
|
|
2420
|
+
}
|
|
2421
|
+
return {
|
|
2422
|
+
kind: block.kind,
|
|
2423
|
+
condition: block.condition,
|
|
2424
|
+
declarations: block.declarations,
|
|
2425
|
+
pseudos: block.pseudos.map((p) => ({ ...p, selector: anchorSelectorList(p.selector) }))
|
|
2426
|
+
};
|
|
2427
|
+
}
|
|
2428
|
+
function emptyResult(diagnostics) {
|
|
2429
|
+
return { atoms: [], diagnostics };
|
|
2430
|
+
}
|
|
2431
|
+
function readNames(components) {
|
|
2432
|
+
const idents = [];
|
|
2433
|
+
const diagnostics = [];
|
|
2434
|
+
for (const component of components) {
|
|
2435
|
+
if (component.kind === "ident") {
|
|
2436
|
+
idents.push(component);
|
|
2437
|
+
continue;
|
|
2438
|
+
}
|
|
2439
|
+
diagnostics.push({
|
|
2440
|
+
code: "bad-token",
|
|
2441
|
+
text: component.text,
|
|
2442
|
+
offset: component.offset,
|
|
2443
|
+
endOffset: component.endOffset
|
|
2444
|
+
});
|
|
2445
|
+
}
|
|
2446
|
+
return { idents, diagnostics };
|
|
2447
|
+
}
|
|
2448
|
+
function readUnknownAtomDiagnostics(components, resolved) {
|
|
2449
|
+
const diagnostics = [];
|
|
2450
|
+
for (const component of components) {
|
|
2451
|
+
if (component.kind !== "ident" || Object.hasOwn(resolved, component.name)) continue;
|
|
2452
|
+
diagnostics.push({
|
|
2453
|
+
code: "unknown-atom",
|
|
2454
|
+
name: component.name,
|
|
2455
|
+
offset: component.offset,
|
|
2456
|
+
endOffset: component.endOffset
|
|
2457
|
+
});
|
|
2458
|
+
}
|
|
2459
|
+
return diagnostics;
|
|
2460
|
+
}
|
|
2461
|
+
function toPlannedAtoms(idents, resolved) {
|
|
2462
|
+
const planned = [];
|
|
2463
|
+
for (const ident of idents) {
|
|
2464
|
+
const atom = Object.hasOwn(resolved, ident.name) ? resolved[ident.name] : void 0;
|
|
2465
|
+
if (!atom) continue;
|
|
2466
|
+
planned.push({
|
|
2467
|
+
name: ident.name,
|
|
2468
|
+
offset: ident.offset,
|
|
2469
|
+
endOffset: ident.endOffset,
|
|
2470
|
+
declarations: atom.declarations,
|
|
2471
|
+
blocks: atom.blocks.map((block) => anchorBlock(block))
|
|
2472
|
+
});
|
|
2473
|
+
}
|
|
2474
|
+
return planned;
|
|
2475
|
+
}
|
|
2476
|
+
function planNames(prelude, options) {
|
|
2477
|
+
const components = readPreludeComponents(prelude);
|
|
2478
|
+
if (components.length === 0) {
|
|
2479
|
+
return emptyResult([{ code: "no-atom", offset: 0, endOffset: prelude.length }]);
|
|
2480
|
+
}
|
|
2481
|
+
const { idents, diagnostics } = readNames(components);
|
|
2482
|
+
const { resolved } = resolve(
|
|
2483
|
+
idents.map((ident) => ident.name),
|
|
2484
|
+
{ extend: options.extend }
|
|
2485
|
+
);
|
|
2486
|
+
diagnostics.push(...readUnknownAtomDiagnostics(components, resolved));
|
|
2487
|
+
diagnostics.sort((a, b) => a.offset - b.offset);
|
|
2488
|
+
return { atoms: toPlannedAtoms(idents, resolved), diagnostics };
|
|
2489
|
+
}
|
|
2490
|
+
function plan(prelude, context, options = {}) {
|
|
2491
|
+
if (!context.isStyleRuleParent) {
|
|
2492
|
+
return emptyResult([{ code: "bad-parent", offset: 0, endOffset: prelude.length }]);
|
|
2493
|
+
}
|
|
2494
|
+
if (context.isInsideKeyframes) {
|
|
2495
|
+
return emptyResult([{ code: "in-keyframes", offset: 0, endOffset: prelude.length }]);
|
|
2496
|
+
}
|
|
2497
|
+
return planNames(prelude, options);
|
|
2498
|
+
}
|
|
2499
|
+
|
|
2500
|
+
// src/directive/order-emitted.ts
|
|
2501
|
+
function declarationNode(ref, declaration) {
|
|
2502
|
+
const { prop, value, important } = toOrderDeclaration(declaration);
|
|
2503
|
+
return { kind: "decl", ref, prop, value, important };
|
|
2504
|
+
}
|
|
2505
|
+
function blockNode(ref, block) {
|
|
2506
|
+
const rule = (selector, declarations) => ({
|
|
2507
|
+
kind: "rule",
|
|
2508
|
+
ref,
|
|
2509
|
+
selector,
|
|
2510
|
+
nodes: declarations.map((declaration) => declarationNode(ref, declaration))
|
|
2511
|
+
});
|
|
2512
|
+
if (block.kind === "pseudo") return rule(block.selector, block.declarations);
|
|
2513
|
+
return {
|
|
2514
|
+
kind: "group",
|
|
2515
|
+
ref,
|
|
2516
|
+
name: block.kind,
|
|
2517
|
+
prelude: block.condition,
|
|
2518
|
+
nodes: [
|
|
2519
|
+
...block.declarations.map((declaration) => declarationNode(ref, declaration)),
|
|
2520
|
+
...block.pseudos.map((pseudo) => rule(pseudo.selector, pseudo.declarations))
|
|
2521
|
+
]
|
|
2522
|
+
};
|
|
2523
|
+
}
|
|
2524
|
+
function plannedDirective(directive, context, cache) {
|
|
2525
|
+
if (cache === void 0) return planNow(directive, context);
|
|
2526
|
+
const key = `${context.isInsideKeyframes ? "k" : "r"}${directive.prelude}`;
|
|
2527
|
+
let planned = cache.get(key);
|
|
2528
|
+
if (planned === void 0) {
|
|
2529
|
+
planned = planNow(directive, context);
|
|
2530
|
+
cache.set(key, planned);
|
|
2531
|
+
}
|
|
2532
|
+
return planned;
|
|
2533
|
+
}
|
|
2534
|
+
function planNow(directive, context) {
|
|
2535
|
+
try {
|
|
2536
|
+
const { atoms: atoms2 } = plan(
|
|
2537
|
+
directive.prelude,
|
|
2538
|
+
{ isStyleRuleParent: true, isInsideKeyframes: context.isInsideKeyframes },
|
|
2539
|
+
{ extend: context.extend }
|
|
2540
|
+
);
|
|
2541
|
+
const nodes = atoms2.flatMap((atom) => [
|
|
2542
|
+
...atom.declarations.map((declaration) => declarationNode(directive.ref, declaration)),
|
|
2543
|
+
...atom.blocks.map((block) => blockNode(directive.ref, block))
|
|
2544
|
+
]);
|
|
2545
|
+
return { atoms: atoms2, nodes };
|
|
2546
|
+
} catch {
|
|
2547
|
+
return { atoms: [], nodes: [] };
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2551
|
+
// src/directive/marker-names.ts
|
|
2552
|
+
var SHORTHANDS = Object.entries(
|
|
2553
|
+
PROPERTY_LONGHANDS
|
|
2554
|
+
).filter(([name, longhands]) => longhands.length > 1 && name !== "all").toSorted((a, b) => b[1].length - a[1].length || a[0].localeCompare(b[0]));
|
|
2555
|
+
function wholeShorthands(set) {
|
|
2556
|
+
const picked = /* @__PURE__ */ new Map();
|
|
2557
|
+
const covered = /* @__PURE__ */ new Set();
|
|
2558
|
+
for (const [name, longhands] of SHORTHANDS) {
|
|
2559
|
+
if (longhands.some((longhand) => !set.has(longhand))) continue;
|
|
2560
|
+
if (longhands.every((longhand) => covered.has(longhand))) continue;
|
|
2561
|
+
picked.set(name, longhands);
|
|
2562
|
+
for (const longhand of longhands) covered.add(longhand);
|
|
2563
|
+
}
|
|
2564
|
+
return picked;
|
|
2565
|
+
}
|
|
2566
|
+
function namesForLonghands(longhands) {
|
|
2567
|
+
const shorthands = wholeShorthands(new Set(longhands));
|
|
2568
|
+
const names = [];
|
|
2569
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2570
|
+
for (const longhand of longhands) {
|
|
2571
|
+
const owner = [...shorthands].find(([, members]) => members.includes(longhand));
|
|
2572
|
+
const name = owner ? owner[0] : longhand;
|
|
2573
|
+
if (!seen.has(name)) names.push(name);
|
|
2574
|
+
seen.add(name);
|
|
2575
|
+
}
|
|
2576
|
+
return names;
|
|
2577
|
+
}
|
|
2578
|
+
|
|
2579
|
+
// src/directive/order-overridden.ts
|
|
2580
|
+
function overriddenByPair(pair) {
|
|
2581
|
+
const block = longhandsOf(pair.block.prop);
|
|
2582
|
+
const later = new Set(longhandsOf(pair.later.prop).map((longhand) => standardName(longhand)));
|
|
2583
|
+
const shared = block.filter((longhand) => later.has(standardName(longhand)));
|
|
2584
|
+
return shared.length > 0 ? shared : block;
|
|
2585
|
+
}
|
|
2586
|
+
function overriddenLonghands(pairs2) {
|
|
2587
|
+
const all = pairs2.flatMap((pair) => overriddenByPair(pair));
|
|
2588
|
+
return [...new Set(all)];
|
|
2589
|
+
}
|
|
2590
|
+
|
|
2591
|
+
// src/directive/migration.ts
|
|
2592
|
+
var MIGRATION_VERSION = "0.5.0";
|
|
2593
|
+
function overriderSentence(atom) {
|
|
2594
|
+
return `Before @navecss/core ${MIGRATION_VERSION} "${atom}" won, because an atom's blocks were placed last in the rule.`;
|
|
2595
|
+
}
|
|
2596
|
+
function wrappedSpecificitySentence() {
|
|
2597
|
+
return `Before @navecss/core ${MIGRATION_VERSION} they were left outside \`& { }\`, so they matched with each selector's own specificity.`;
|
|
2598
|
+
}
|
|
2599
|
+
function wrappedPseudoElementSentence() {
|
|
2600
|
+
return `Before @navecss/core ${MIGRATION_VERSION} they did, because they were left outside \`& { }\`.`;
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2603
|
+
// src/directive/order-focus.ts
|
|
2604
|
+
var RING_CLAUSE = 'This hides the keyboard focus indicator that "focusRing" draws.';
|
|
2605
|
+
var REVEAL_CLAUSE = 'This hides again what "srOnlyFocusable" reveals on focus, such as a skip link.';
|
|
2606
|
+
var OUTLINE_PROPERTIES = /* @__PURE__ */ new Set([
|
|
2607
|
+
"all",
|
|
2608
|
+
"outline",
|
|
2609
|
+
"outline-color",
|
|
2610
|
+
"outline-style",
|
|
2611
|
+
"outline-width"
|
|
2612
|
+
]);
|
|
2613
|
+
var STYLE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2614
|
+
"auto",
|
|
2615
|
+
"dashed",
|
|
2616
|
+
"dotted",
|
|
2617
|
+
"double",
|
|
2618
|
+
"groove",
|
|
2619
|
+
"inset",
|
|
2620
|
+
"outset",
|
|
2621
|
+
"ridge",
|
|
2622
|
+
"solid"
|
|
2623
|
+
]);
|
|
2624
|
+
var UNJUDGED_FUNCTIONS = /* @__PURE__ */ new Set(["attr", "env", "var"]);
|
|
2625
|
+
var STYLE_RESETTING = /* @__PURE__ */ new Set(["all", "outline", "outline-style"]);
|
|
2626
|
+
var DECIDED_ELSEWHERE = /* @__PURE__ */ new Set(["inherit", "revert", "revert-layer"]);
|
|
2627
|
+
function significantTokens(value) {
|
|
2628
|
+
return tokenize(value).filter((t) => t.type !== "whitespace-token" && t.type !== "comment");
|
|
2629
|
+
}
|
|
2630
|
+
function compact(value) {
|
|
2631
|
+
return significantTokens(value).map((token) => token.raw).join("").toLowerCase();
|
|
2632
|
+
}
|
|
2633
|
+
function identOf(token) {
|
|
2634
|
+
return token?.type === "ident-token" ? String(token.structured?.value).toLowerCase() : void 0;
|
|
2635
|
+
}
|
|
2636
|
+
function isZero(token) {
|
|
2637
|
+
return (token.type === "number-token" || token.type === "dimension-token") && token.structured.value === 0;
|
|
2638
|
+
}
|
|
2639
|
+
var BLOCK_OPENERS = /* @__PURE__ */ new Set(["(-token", "[-token", "function-token", "{-token"]);
|
|
2640
|
+
var BLOCK_CLOSERS = /* @__PURE__ */ new Set([")-token", "]-token", "}-token"]);
|
|
2641
|
+
function topLevelTokens(tokens) {
|
|
2642
|
+
let depth = 0;
|
|
2643
|
+
const kept = [];
|
|
2644
|
+
for (const token of tokens) {
|
|
2645
|
+
if (BLOCK_OPENERS.has(token.type)) depth += 1;
|
|
2646
|
+
else if (BLOCK_CLOSERS.has(token.type)) depth = Math.max(0, depth - 1);
|
|
2647
|
+
else if (depth === 0) kept.push(token);
|
|
2648
|
+
}
|
|
2649
|
+
return kept;
|
|
2650
|
+
}
|
|
2651
|
+
function isOutlineShorthandHiding(tokens) {
|
|
2652
|
+
const top = topLevelTokens(tokens);
|
|
2653
|
+
const idents = top.map((token) => identOf(token));
|
|
2654
|
+
if (idents.every((ident) => ident === void 0 || !STYLE_KEYWORDS.has(ident))) return true;
|
|
2655
|
+
return top.some((token) => isZero(token)) || idents.includes("transparent");
|
|
2656
|
+
}
|
|
2657
|
+
function isAutoStyle(declaration) {
|
|
2658
|
+
const property = declaration.prop.toLowerCase();
|
|
2659
|
+
const tokens = significantTokens(declaration.value);
|
|
2660
|
+
if (property === "outline-style") return identOf(tokens[0]) === "auto";
|
|
2661
|
+
if (property !== "outline") return false;
|
|
2662
|
+
return topLevelTokens(tokens).some((token) => identOf(token) === "auto");
|
|
2663
|
+
}
|
|
2664
|
+
function keywordHides(property, keyword) {
|
|
2665
|
+
if (keyword === "initial" || keyword === "unset") return STYLE_RESETTING.has(property);
|
|
2666
|
+
if (DECIDED_ELSEWHERE.has(keyword)) return false;
|
|
2667
|
+
return void 0;
|
|
2668
|
+
}
|
|
2669
|
+
function isRingHiddenByValue(property, tokens) {
|
|
2670
|
+
if (property === "outline") return isOutlineShorthandHiding(tokens);
|
|
2671
|
+
if (property === "outline-style") return identOf(tokens[0]) === "none";
|
|
2672
|
+
if (property === "outline-width") return tokens.length === 1 && isZero(tokens[0]);
|
|
2673
|
+
if (property === "outline-color") return identOf(tokens[0]) === "transparent";
|
|
2674
|
+
return false;
|
|
2675
|
+
}
|
|
2676
|
+
function isRingHidden(declaration) {
|
|
2677
|
+
const property = declaration.prop.toLowerCase();
|
|
2678
|
+
if (!OUTLINE_PROPERTIES.has(property)) return false;
|
|
2679
|
+
const tokens = significantTokens(declaration.value);
|
|
2680
|
+
if (tokens.some(
|
|
2681
|
+
(t) => t.type === "function-token" && UNJUDGED_FUNCTIONS.has(String(t.structured?.value).toLowerCase())
|
|
2682
|
+
)) {
|
|
2683
|
+
return false;
|
|
2684
|
+
}
|
|
2685
|
+
const keyword = tokens.length === 1 ? identOf(tokens[0]) : void 0;
|
|
2686
|
+
const judged = keyword === void 0 ? void 0 : keywordHides(property, keyword);
|
|
2687
|
+
return judged ?? isRingHiddenByValue(property, tokens);
|
|
2688
|
+
}
|
|
2689
|
+
function isRingHiddenInBlock(declaration, siblings) {
|
|
2690
|
+
return isRingHidden(declaration) && siblings.every((sibling) => !isAutoStyle(sibling));
|
|
2691
|
+
}
|
|
2692
|
+
function isClipPathInset(declaration) {
|
|
2693
|
+
return declaration.prop.toLowerCase() === "clip-path" && compact(declaration.value) === "inset(50%)";
|
|
2694
|
+
}
|
|
2695
|
+
function isHidingSize(declaration) {
|
|
2696
|
+
const prop = declaration.prop.toLowerCase();
|
|
2697
|
+
return (prop === "width" || prop === "height") && compact(declaration.value) === "1px";
|
|
2698
|
+
}
|
|
2699
|
+
function isHidingTrio(declarations) {
|
|
2700
|
+
const isPresent = (prop, value) => declarations.some((d) => d.prop.toLowerCase() === prop && compact(d.value) === value);
|
|
2701
|
+
return isPresent("width", "1px") && isPresent("height", "1px") && isPresent("overflow", "hidden");
|
|
2702
|
+
}
|
|
2703
|
+
function isRevealHidden(declaration, siblings) {
|
|
2704
|
+
if (isClipPathInset(declaration)) return true;
|
|
2705
|
+
const prop = declaration.prop.toLowerCase();
|
|
2706
|
+
const isTrioMember = isHidingSize(declaration) || prop === "overflow" && compact(declaration.value) === "hidden";
|
|
2707
|
+
return isTrioMember && isHidingTrio(siblings);
|
|
2708
|
+
}
|
|
2709
|
+
function focusClauseOf(finding) {
|
|
2710
|
+
const { atom } = finding.unit;
|
|
2711
|
+
const { declaration, siblings } = finding.candidate;
|
|
2712
|
+
if (atom.name === "focusRing" && isRingHiddenInBlock(declaration, siblings)) return RING_CLAUSE;
|
|
2713
|
+
if (atom.name === "srOnlyFocusable" && isRevealHidden(declaration, siblings)) return REVEAL_CLAUSE;
|
|
2714
|
+
return void 0;
|
|
2715
|
+
}
|
|
2716
|
+
|
|
2717
|
+
// src/directive/order-text.ts
|
|
2718
|
+
function joinList(items, conjunction = "and") {
|
|
2719
|
+
if (items.length <= 1) return items.join("");
|
|
2720
|
+
return `${items.slice(0, -1).join(", ")} ${conjunction} ${items.at(-1)}`;
|
|
2721
|
+
}
|
|
2722
|
+
function isLaterContaining(pair) {
|
|
2723
|
+
const later = new Set(longhandsOf(pair.later.prop).map((longhand) => standardName(longhand)));
|
|
2724
|
+
return longhandsOf(pair.block.prop).every((longhand) => later.has(standardName(longhand)));
|
|
2725
|
+
}
|
|
2726
|
+
function isBareDeclaration(finding) {
|
|
2727
|
+
const { overrider } = finding.candidate;
|
|
2728
|
+
return overrider.kind === "own" && overrider.top.kind === "declaration";
|
|
2729
|
+
}
|
|
2730
|
+
function overriddenName(pair) {
|
|
2731
|
+
const block = new Set(longhandsOf(pair.block.prop).map((longhand) => standardName(longhand)));
|
|
2732
|
+
const later = longhandsOf(pair.later.prop).map((longhand) => standardName(longhand));
|
|
2733
|
+
if (later.every((longhand) => block.has(longhand))) {
|
|
2734
|
+
const standard = standardName(pair.later.prop);
|
|
2735
|
+
return standard === pair.later.prop.toLowerCase() ? pair.later.prop : standard;
|
|
2736
|
+
}
|
|
2737
|
+
return joinList([...new Set(later.filter((longhand) => block.has(longhand)))]);
|
|
2738
|
+
}
|
|
2739
|
+
function valueClause(finding) {
|
|
2740
|
+
const [first] = finding.pairs;
|
|
2741
|
+
const { block, later } = first;
|
|
2742
|
+
const isBare = isBareDeclaration(finding);
|
|
2743
|
+
const blockValue = printedValue(block.value);
|
|
2744
|
+
const laterValue = printedValue(later.value);
|
|
2745
|
+
if (finding.pairs.length > 1 || !isSameProperty(block.prop, later.prop) && isLaterContaining(first)) {
|
|
2746
|
+
const list = joinList([...new Set(finding.pairs.map((pair) => pair.block.prop))]);
|
|
2747
|
+
return `${later.prop}: ${laterValue} replaces ${list}`;
|
|
2748
|
+
}
|
|
2749
|
+
if (isSameProperty(block.prop, later.prop)) {
|
|
2750
|
+
return `${block.prop} is ${laterValue}, not ${blockValue}`;
|
|
2751
|
+
}
|
|
2752
|
+
const subject = isBare ? "it" : `its ${later.prop}: ${laterValue}`;
|
|
2753
|
+
if (isLogicalPhysicalPair(block.prop, later.prop)) {
|
|
2754
|
+
return `${subject} may override ${block.prop}: ${blockValue}, depending on writing mode`;
|
|
2755
|
+
}
|
|
2756
|
+
return `${subject} replaces the ${overriddenName(first)} that ${block.prop}: ${blockValue} sets`;
|
|
2757
|
+
}
|
|
2758
|
+
function placeClause(finding) {
|
|
2759
|
+
const { unit, candidate } = finding;
|
|
2760
|
+
const placed = {
|
|
2761
|
+
conditions: unit.conditions,
|
|
2762
|
+
said: unit.placeStates,
|
|
2763
|
+
selector: unit.placeSelector ?? unit.selector
|
|
2764
|
+
};
|
|
2765
|
+
const place = whereOf(placed.selector, unit.conditions);
|
|
2766
|
+
const also = alsoWhere(placed, {
|
|
2767
|
+
selector: candidate.holderSelector,
|
|
2768
|
+
conditions: candidate.conditions
|
|
2769
|
+
});
|
|
2770
|
+
return also === "" ? place : `${place} while also ${also},`;
|
|
2771
|
+
}
|
|
2772
|
+
function overriderName(finding) {
|
|
2773
|
+
const { overrider, declaration } = finding.candidate;
|
|
2774
|
+
if (overrider.kind === "atom") return `"${overrider.atom.name}"`;
|
|
2775
|
+
if (overrider.top.kind === "declaration") {
|
|
2776
|
+
return `${declaration.prop}: ${printedValue(declaration.value)}`;
|
|
2777
|
+
}
|
|
2778
|
+
if (finding.outward?.overrider !== void 0) return finding.outward.overrider;
|
|
2779
|
+
if (overrider.top.kind === "rule") return `the ${printedValue(overrider.top.selector)} block`;
|
|
2780
|
+
return `the @${overrider.top.name} ${printedValue(overrider.top.prelude)} block`;
|
|
2781
|
+
}
|
|
2782
|
+
function fixSentence(finding, context) {
|
|
2783
|
+
if (finding.canMove?.() !== true) return void 0;
|
|
2784
|
+
const { unit, candidate } = finding;
|
|
2785
|
+
const atom = `"${unit.atom.name}"`;
|
|
2786
|
+
const { overrider } = candidate;
|
|
2787
|
+
if (finding.outward !== void 0) {
|
|
2788
|
+
const moved = overrider.kind === "own" ? overriderName(finding) : `the directive that names "${overrider.atom.name}"`;
|
|
2789
|
+
return `To let ${atom} win, move ${moved} above ${finding.outward.above}.`;
|
|
2790
|
+
}
|
|
2791
|
+
if (overrider.kind === "own")
|
|
2792
|
+
return `To let ${atom} win, move ${overriderName(finding)} above the directive.`;
|
|
2793
|
+
const later = `"${overrider.atom.name}"`;
|
|
2794
|
+
if (overrider.directive.ref !== unit.directive.ref || context.moveAfter === void 0) {
|
|
2795
|
+
return `To let ${atom} win, move it into the later directive, after ${later}.`;
|
|
2796
|
+
}
|
|
2797
|
+
const occurrences = unit.directive.atoms.filter((named) => named.name === unit.atom.name);
|
|
2798
|
+
const printed = reorderedDirective(unit.directive.prelude, unit.directive.atoms, {
|
|
2799
|
+
moving: occurrences.map((named) => named.atomIndex),
|
|
2800
|
+
after: context.moveAfter
|
|
2801
|
+
});
|
|
2802
|
+
return `To let ${atom} win, name it after ${later}: \`${printed}\`.`;
|
|
2803
|
+
}
|
|
2804
|
+
function markerSentence(finding, context) {
|
|
2805
|
+
const { unit, candidate } = finding;
|
|
2806
|
+
const { overrider } = candidate;
|
|
2807
|
+
const printed = `\`${context.markedDirective}\``;
|
|
2808
|
+
if (overrider.kind === "own") {
|
|
2809
|
+
return `If it is meant to win, mark the directive that names "${unit.atom.name}": ${printed}`;
|
|
2810
|
+
}
|
|
2811
|
+
const isSameDirective = overrider.directive.ref === unit.directive.ref;
|
|
2812
|
+
const target = isSameDirective ? "mark the directive" : `mark the directive that names "${unit.atom.name}"`;
|
|
2813
|
+
return `If "${overrider.atom.name}" is meant to win, ${target}: ${printed}`;
|
|
2814
|
+
}
|
|
2815
|
+
function migrationSentence(finding) {
|
|
2816
|
+
const { overrider } = finding.candidate;
|
|
2817
|
+
const isBlock = overrider.kind === "atom" && overrider.isBlock;
|
|
2818
|
+
if (isBlock || finding.outward !== void 0) return void 0;
|
|
2819
|
+
return overriderSentence(finding.unit.atom.name);
|
|
2820
|
+
}
|
|
2821
|
+
function findingText(finding, context) {
|
|
2822
|
+
const opening = `${overriderName(finding)} comes after "${finding.unit.atom.name}"`;
|
|
2823
|
+
const reason = `so ${placeClause(finding)} ${valueClause(finding)}.`;
|
|
2824
|
+
const sentences = [
|
|
2825
|
+
`@nave: ${opening}, ${reason}`,
|
|
2826
|
+
focusClauseOf(finding),
|
|
2827
|
+
migrationSentence(finding),
|
|
2828
|
+
fixSentence(finding, context),
|
|
2829
|
+
markerSentence(finding, context)
|
|
2830
|
+
];
|
|
2831
|
+
return sentences.filter((sentence) => sentence !== void 0).join(" ");
|
|
2832
|
+
}
|
|
2833
|
+
|
|
2834
|
+
// src/directive/order-warnings.ts
|
|
2835
|
+
function anchorOf(finding) {
|
|
2836
|
+
const { overrider } = finding.candidate;
|
|
2837
|
+
if (overrider.kind === "atom") {
|
|
2838
|
+
return { ref: overrider.directive.ref, offset: overrider.atom.offset };
|
|
2839
|
+
}
|
|
2840
|
+
return { ref: overrider.topRef, offset: void 0 };
|
|
2841
|
+
}
|
|
2842
|
+
function remainingLonghands(finding, markers) {
|
|
2843
|
+
const covered = coveredLonghands(markers, finding.candidate.declaration.prop);
|
|
2844
|
+
if (covered.has("*")) return [];
|
|
2845
|
+
return overriddenLonghands(finding.pairs).filter(
|
|
2846
|
+
(longhand) => !covered.has(standardName(longhand))
|
|
2847
|
+
);
|
|
2848
|
+
}
|
|
2849
|
+
function warningOf(finding, all) {
|
|
2850
|
+
const { prelude } = finding.unit.directive;
|
|
2851
|
+
const remaining = remainingLonghands(finding, readMarkers(prelude).markers);
|
|
2852
|
+
if (remaining.length === 0) return void 0;
|
|
2853
|
+
const names = namesForLonghands(remaining);
|
|
2854
|
+
const context = {
|
|
2855
|
+
markedDirective: markedDirective(prelude, names),
|
|
2856
|
+
moveAfter: lastOverriderIndex(finding, all)
|
|
2857
|
+
};
|
|
2858
|
+
return { anchor: anchorOf(finding), text: findingText(finding, context) };
|
|
2859
|
+
}
|
|
2860
|
+
function findingWarnings(findings) {
|
|
2861
|
+
return findings.flatMap((finding) => warningOf(finding, findings) ?? []);
|
|
2862
|
+
}
|
|
2863
|
+
function isUsed(name, findings) {
|
|
2864
|
+
if (name.toLowerCase() === "all") {
|
|
2865
|
+
return findings.some((f) => f.candidate.declaration.prop.toLowerCase() === "all");
|
|
2866
|
+
}
|
|
2867
|
+
const covered = new Set(longhandsCoveredBy(name));
|
|
2868
|
+
return findings.some(
|
|
2869
|
+
(f) => overriddenLonghands(f.pairs).some((longhand) => covered.has(standardName(longhand)))
|
|
2870
|
+
);
|
|
2871
|
+
}
|
|
2872
|
+
function nameReport(name, findings, isStaleReported) {
|
|
2873
|
+
if (!isCssProperty(name)) {
|
|
2874
|
+
return `@nave: the marker on this directive names "${name}", which is not a CSS property, so it allows nothing. The marker takes property names, such as display, not atom names.`;
|
|
2875
|
+
}
|
|
2876
|
+
if (!isStaleReported || isUsed(name, findings)) return void 0;
|
|
2877
|
+
return `@nave: the marker on this directive names ${name}, but nothing after the directive overrides ${name} in its atoms' blocks. Remove ${name} from the marker.`;
|
|
2878
|
+
}
|
|
2879
|
+
function markerReports(directive, findings, options) {
|
|
2880
|
+
const { isStaleReported, outwardFor } = options;
|
|
2881
|
+
const mine = [
|
|
2882
|
+
...findings.filter((finding) => finding.unit.directive.ref === directive.ref),
|
|
2883
|
+
...outwardFor(directive)
|
|
2884
|
+
];
|
|
2885
|
+
const { markers, malformed } = readMarkers(directive.prelude);
|
|
2886
|
+
const reports = [];
|
|
2887
|
+
for (const marker of markers) {
|
|
2888
|
+
if (marker.names.length === 0) {
|
|
2889
|
+
reports.push({
|
|
2890
|
+
start: marker.start,
|
|
2891
|
+
text: "@nave: the nave-allow-override marker on this directive names no property, so it allows nothing. Name the property a warning reported, or remove the marker."
|
|
2892
|
+
});
|
|
2893
|
+
}
|
|
2894
|
+
for (const name of marker.names) {
|
|
2895
|
+
const text = nameReport(name, mine, isStaleReported);
|
|
2896
|
+
if (text) reports.push({ start: marker.start, text });
|
|
2897
|
+
}
|
|
2898
|
+
}
|
|
2899
|
+
for (const bad of malformed) {
|
|
2900
|
+
reports.push({
|
|
2901
|
+
start: bad.start,
|
|
2902
|
+
text: `@nave: the comment ${bad.text} in this directive is not a marker, so it allows nothing: a marker starts with nave-allow-override and a colon, with nothing between them, such as \`/* nave-allow-override: display */\`. Correct the comment, or remove it.`
|
|
2903
|
+
});
|
|
2904
|
+
}
|
|
2905
|
+
return reports.toSorted((a, b) => a.start - b.start).map(({ start, text }) => ({ anchor: { ref: directive.ref, offset: start }, text }));
|
|
2906
|
+
}
|
|
2907
|
+
function markerWarnings(directives, findings, isStaleReported, outwardFor) {
|
|
2908
|
+
const options = { isStaleReported, outwardFor };
|
|
2909
|
+
return directives.flatMap((directive) => markerReports(directive, findings, options));
|
|
2910
|
+
}
|
|
2911
|
+
|
|
2912
|
+
// src/directive/rule-state.ts
|
|
2913
|
+
function createState(input) {
|
|
2914
|
+
return {
|
|
2915
|
+
above: void 0,
|
|
2916
|
+
directives: [],
|
|
2917
|
+
dropped: [],
|
|
2918
|
+
directiveTotal: input.nodes.filter((node) => node.kind === "directive").length,
|
|
2919
|
+
hasOwnNested: false,
|
|
2920
|
+
input,
|
|
2921
|
+
isNested: false,
|
|
2922
|
+
isPseudoElementRule: isPseudoElementOnlyList(input.selector),
|
|
2923
|
+
items: [],
|
|
2924
|
+
lastDirective: void 0,
|
|
2925
|
+
lastNested: void 0,
|
|
2926
|
+
ownDeclarationSinceAbove: false,
|
|
2927
|
+
run: { refs: [], trailing: [] },
|
|
2928
|
+
runs: [],
|
|
2929
|
+
segments: []
|
|
2930
|
+
};
|
|
2931
|
+
}
|
|
2932
|
+
|
|
2933
|
+
// src/directive/shape-warnings.ts
|
|
2934
|
+
var WRAP = "`& { }`";
|
|
2935
|
+
function splitSelectors(list) {
|
|
2936
|
+
const all = splitTopLevel(list).map((selector) => selector.trim()).filter((selector) => selector !== "");
|
|
2937
|
+
return {
|
|
2938
|
+
pseudoElements: all.filter((selector) => endsInPseudoElement(selector)),
|
|
2939
|
+
others: all.filter((selector) => !endsInPseudoElement(selector))
|
|
2940
|
+
};
|
|
2941
|
+
}
|
|
2942
|
+
function quoted(names) {
|
|
2943
|
+
return joinList(names.map((name) => `"${name}"`));
|
|
2944
|
+
}
|
|
2945
|
+
function anchorOf2(run) {
|
|
2946
|
+
if (run.kind === "own") return { ref: run.anchorRef, offset: void 0 };
|
|
2947
|
+
return { ref: run.directive.ref, offset: run.atoms[0].offset };
|
|
2948
|
+
}
|
|
2949
|
+
function pseudoElementText(run, pseudo) {
|
|
2950
|
+
const other = `Or move ${pseudo} to a separate rule, with or without them.`;
|
|
2951
|
+
if (run.kind === "own") {
|
|
2952
|
+
return `@nave: the declarations after ${run.nested} are written inside ${WRAP}, which cannot match a pseudo-element, so they do not apply to ${pseudo}. ${wrappedPseudoElementSentence()} To apply them there too, move them above ${run.above}. ${other}`;
|
|
2953
|
+
}
|
|
2954
|
+
const atoms2 = quoted(run.atoms.map((atom) => atom.name));
|
|
2955
|
+
const sentence = run.isWrappedBefore ? "" : ` ${wrappedPseudoElementSentence()}`;
|
|
2956
|
+
const separate = `Move ${pseudo} to a separate rule, with or without them.`;
|
|
2957
|
+
if (run.follows) return followsText(run, { atoms: atoms2, pseudo, sentence, separate, other });
|
|
2958
|
+
const nestedSentence = run.nested.block && !run.isWrappedBefore ? sentence : "";
|
|
2959
|
+
const move = run.canMoveDirective ? ` To apply them there too, move the directive above ${run.above}. ${other}` : ` ${separate}`;
|
|
2960
|
+
return `@nave: this directive comes after ${run.nested.text}, so the declarations of ${atoms2} are written inside ${WRAP}, which cannot match a pseudo-element: they do not apply to ${pseudo}.${nestedSentence}${move}`;
|
|
2961
|
+
}
|
|
2962
|
+
function followsText(run, parts) {
|
|
2963
|
+
const { follows } = run;
|
|
2964
|
+
const head = `@nave: the declarations of ${parts.atoms} follow the block of "${follows.atom.name}" ${follows.where}, so they are written inside ${WRAP}, which cannot match a pseudo-element: they do not apply to ${parts.pseudo}.${parts.sentence}`;
|
|
2965
|
+
if (!run.canReorder) return `${head} ${parts.separate}`;
|
|
2966
|
+
const printed = directiveWithAtomsBefore(run.directive.prelude, run.directive.atoms, {
|
|
2967
|
+
moving: run.atoms.map((atom) => atom.atomIndex),
|
|
2968
|
+
before: follows.atom.atomIndex
|
|
2969
|
+
});
|
|
2970
|
+
return `${head} To apply them there too, name ${parts.atoms} before "${follows.atom.name}": \`${printed}\`. ${parts.other}`;
|
|
2971
|
+
}
|
|
2972
|
+
function groupsText(selectors, specificities) {
|
|
2973
|
+
const groups = [];
|
|
2974
|
+
for (const [index, selector] of selectors.others.entries()) {
|
|
2975
|
+
const specificity = specificities[index];
|
|
2976
|
+
const group = groups.find((g) => compareSpecificity(g.specificity, specificity) === 0);
|
|
2977
|
+
if (group) group.members.push(selector);
|
|
2978
|
+
else groups.push({ specificity, members: [selector] });
|
|
2979
|
+
}
|
|
2980
|
+
groups[0].members.push(...selectors.pseudoElements);
|
|
2981
|
+
return joinList(groups.map((group) => `\`${group.members.join(", ")}\``));
|
|
2982
|
+
}
|
|
2983
|
+
function wrapText(run, selectors) {
|
|
2984
|
+
const specificities = selectors.others.map((selector) => ampersandSpecificity(selector));
|
|
2985
|
+
const highest = maxSpecificity(specificities);
|
|
2986
|
+
const mostIndex = specificities.findIndex((s) => compareSpecificity(s, highest) === 0);
|
|
2987
|
+
const most = selectors.others[mostIndex];
|
|
2988
|
+
const less = selectors.others.filter(
|
|
2989
|
+
(_s, i) => compareSpecificity(specificities[i], highest) < 0
|
|
2990
|
+
);
|
|
2991
|
+
const list = selectors.others.join(", ");
|
|
2992
|
+
const wholeList = [`:is(${list})`, ...selectors.pseudoElements].join(", ");
|
|
2993
|
+
const subject = run.kind === "own" ? `the declarations after ${run.nested}` : `the declarations of ${quoted(run.atoms.map((atom) => atom.name))}`;
|
|
2994
|
+
const sentence = run.kind === "directive" && run.isWrappedBefore ? "" : ` ${wrappedSpecificitySentence()}`;
|
|
2995
|
+
return `@nave: ${subject} are written inside ${WRAP}, which under the selector list ${list} matches with the specificity of ${most}, so where ${joinList(less, "or")} matches they can win over a rule elsewhere that is more specific than ${joinList(less, "or")}.${sentence} To give each selector its own specificity, write the rule once for each of ${groupsText(selectors, specificities)}. To give the whole rule the specificity of ${most}, write the list as \`${wholeList}\`.`;
|
|
2996
|
+
}
|
|
2997
|
+
function isUnequal(selectors) {
|
|
2998
|
+
const [first, ...rest] = selectors.others.map((selector) => ampersandSpecificity(selector));
|
|
2999
|
+
return first !== void 0 && rest.some((s) => compareSpecificity(s, first) !== 0);
|
|
3000
|
+
}
|
|
3001
|
+
function droppedWarning(fact) {
|
|
3002
|
+
const blocks = fact.atoms.flatMap(
|
|
3003
|
+
({ atom, wheres }) => wheres.map((where) => `the block of "${atom.name}" ${where}`)
|
|
3004
|
+
);
|
|
3005
|
+
const atoms2 = quoted(fact.atoms.map(({ atom }) => atom.name));
|
|
3006
|
+
const declarations = fact.atoms.flatMap(({ declarations: own }) => own.map((d) => `${d.prop}: ${d.value}`)).join("; ");
|
|
3007
|
+
const tail = declarations === "" ? "" : ` and write these declarations in the rule instead: \`${declarations}\``;
|
|
3008
|
+
return {
|
|
3009
|
+
anchor: { ref: fact.directive.ref, offset: void 0 },
|
|
3010
|
+
text: `@nave: every selector in this rule ends in a pseudo-element, and an atom's pseudo-class, @media and @container blocks are written on \`&\`, which cannot match one, so this directive leaves out ${joinList(blocks)}. Remove ${atoms2} from the directive${tail}. If a block was meant for the pseudo-element, write a rule for the pseudo-element under that condition yourself.`
|
|
3011
|
+
};
|
|
3012
|
+
}
|
|
3013
|
+
function shapeWarnings(state) {
|
|
3014
|
+
if (state.isPseudoElementRule) return state.dropped.map((fact) => droppedWarning(fact));
|
|
3015
|
+
if (state.runs.length === 0) return [];
|
|
3016
|
+
const selectors = splitSelectors(state.input.selector);
|
|
3017
|
+
const isMixed = selectors.pseudoElements.length > 0 && selectors.others.length > 0;
|
|
3018
|
+
const hasUnequal = isUnequal(selectors);
|
|
3019
|
+
const pseudo = selectors.pseudoElements.join(", ");
|
|
3020
|
+
return state.runs.flatMap((run) => {
|
|
3021
|
+
const anchor = anchorOf2(run);
|
|
3022
|
+
const found = [];
|
|
3023
|
+
if (isMixed) found.push({ anchor, text: pseudoElementText(run, pseudo) });
|
|
3024
|
+
if (hasUnequal) found.push({ anchor, text: wrapText(run, selectors) });
|
|
3025
|
+
return found;
|
|
3026
|
+
});
|
|
3027
|
+
}
|
|
3028
|
+
|
|
3029
|
+
// src/directive/rule-plan.ts
|
|
3030
|
+
var DirectiveFailure = class extends Error {
|
|
3031
|
+
cause;
|
|
3032
|
+
ref;
|
|
3033
|
+
constructor(ref, cause) {
|
|
3034
|
+
super(cause instanceof Error ? cause.message : String(cause));
|
|
3035
|
+
this.ref = ref;
|
|
3036
|
+
this.cause = cause;
|
|
3037
|
+
}
|
|
3038
|
+
};
|
|
3039
|
+
function isRunWrapped(state) {
|
|
3040
|
+
return state.lastDirective !== void 0 && state.isNested && !state.isPseudoElementRule;
|
|
3041
|
+
}
|
|
3042
|
+
function flushRun(state) {
|
|
3043
|
+
const { run, items } = state;
|
|
3044
|
+
if (run.refs.length > 0) {
|
|
3045
|
+
if (isRunWrapped(state)) {
|
|
3046
|
+
items.push({ kind: "wrap", refs: run.refs, after: state.lastDirective });
|
|
3047
|
+
state.runs.push({
|
|
3048
|
+
kind: "own",
|
|
3049
|
+
anchorRef: run.refs[0],
|
|
3050
|
+
above: state.above ?? "",
|
|
3051
|
+
nested: state.lastNested?.text ?? ""
|
|
3052
|
+
});
|
|
3053
|
+
} else {
|
|
3054
|
+
for (const ref of run.refs) items.push({ kind: "keep", ref });
|
|
3055
|
+
}
|
|
3056
|
+
}
|
|
3057
|
+
for (const ref of run.trailing) items.push({ kind: "keep", ref });
|
|
3058
|
+
run.refs = [];
|
|
3059
|
+
run.trailing = [];
|
|
3060
|
+
}
|
|
3061
|
+
function takeIntoRun(state, node) {
|
|
3062
|
+
const { run } = state;
|
|
3063
|
+
if (node.kind === "decl") {
|
|
3064
|
+
run.refs.push(...run.trailing, node.ref);
|
|
3065
|
+
run.trailing = [];
|
|
3066
|
+
if (state.above !== void 0) state.ownDeclarationSinceAbove = true;
|
|
3067
|
+
} else if (run.refs.length === 0) {
|
|
3068
|
+
state.items.push({ kind: "keep", ref: node.ref });
|
|
3069
|
+
} else {
|
|
3070
|
+
run.trailing.push(node.ref);
|
|
3071
|
+
}
|
|
3072
|
+
}
|
|
3073
|
+
function planDirective(state, node) {
|
|
3074
|
+
try {
|
|
3075
|
+
return plan(
|
|
3076
|
+
node.prelude,
|
|
3077
|
+
{ isStyleRuleParent: true, isInsideKeyframes: state.input.isInsideKeyframes },
|
|
3078
|
+
{ extend: state.input.extend }
|
|
3079
|
+
);
|
|
3080
|
+
} catch (error) {
|
|
3081
|
+
throw new DirectiveFailure(node.ref, error);
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
function expandDirective(state, node) {
|
|
3085
|
+
flushRun(state);
|
|
3086
|
+
const result = planDirective(state, node);
|
|
3087
|
+
const directive = directiveFacts(node, result);
|
|
3088
|
+
state.directives.push(directive);
|
|
3089
|
+
recordSegments(state, directive, result.atoms);
|
|
3090
|
+
state.items.push({
|
|
3091
|
+
kind: "expand",
|
|
3092
|
+
ref: node.ref,
|
|
3093
|
+
emissions: emitAtoms(state, directive, result.atoms),
|
|
3094
|
+
diagnostics: result.diagnostics
|
|
3095
|
+
});
|
|
3096
|
+
state.lastDirective = node.ref;
|
|
3097
|
+
}
|
|
3098
|
+
function keepNested(state, node) {
|
|
3099
|
+
flushRun(state);
|
|
3100
|
+
state.items.push({ kind: "keep", ref: node.ref });
|
|
3101
|
+
state.isNested = true;
|
|
3102
|
+
state.hasOwnNested = true;
|
|
3103
|
+
state.lastNested = { text: nestedText(node) };
|
|
3104
|
+
state.above ??= nestedText(node);
|
|
3105
|
+
}
|
|
3106
|
+
function warningsOf(state) {
|
|
3107
|
+
const { emittedCache, extend, isInsideKeyframes, outward } = state.input;
|
|
3108
|
+
const findings = canHoldPair(state.segments) ? checkOrder(
|
|
3109
|
+
state.segments,
|
|
3110
|
+
ampersandSpecificity(state.input.selector),
|
|
3111
|
+
(directive) => plannedDirective(directive, { extend, isInsideKeyframes }, emittedCache),
|
|
3112
|
+
state.isPseudoElementRule
|
|
3113
|
+
) : [];
|
|
3114
|
+
const knownFor = (directive) => outward?.known.get(outward.identityOf(directive.ref)) ?? [];
|
|
3115
|
+
const warnings = [
|
|
3116
|
+
...findingWarnings(findings),
|
|
3117
|
+
...markerWarnings(
|
|
3118
|
+
state.directives,
|
|
3119
|
+
findings,
|
|
3120
|
+
state.input.reportStaleMarkers !== false,
|
|
3121
|
+
knownFor
|
|
3122
|
+
),
|
|
3123
|
+
...shapeWarnings(state)
|
|
3124
|
+
];
|
|
3125
|
+
return {
|
|
3126
|
+
outwardFindings: findings.filter((finding) => finding.outward !== void 0),
|
|
3127
|
+
warnings: warnings.toSorted(
|
|
3128
|
+
(a, b) => a.anchor.ref - b.anchor.ref || (a.anchor.offset ?? -1) - (b.anchor.offset ?? -1)
|
|
3129
|
+
)
|
|
3130
|
+
};
|
|
3131
|
+
}
|
|
3132
|
+
function planRule(input) {
|
|
3133
|
+
const state = createState(input);
|
|
3134
|
+
for (const node of input.nodes) {
|
|
3135
|
+
if (node.kind === "decl" || node.kind === "comment") takeIntoRun(state, node);
|
|
3136
|
+
else if (node.kind === "directive") expandDirective(state, node);
|
|
3137
|
+
else keepNested(state, node);
|
|
3138
|
+
if (node.kind !== "comment" && node.kind !== "directive") {
|
|
3139
|
+
state.segments.push({ kind: "own", node });
|
|
3140
|
+
}
|
|
3141
|
+
}
|
|
3142
|
+
flushRun(state);
|
|
3143
|
+
return { items: state.items, ...warningsOf(state) };
|
|
3144
|
+
}
|
|
3145
|
+
|
|
3146
|
+
// src/directive/expand-text-apply.ts
|
|
3147
|
+
function significantEnd(w, item) {
|
|
3148
|
+
let last = item.end - 1;
|
|
3149
|
+
while (last > item.start && w.tokens[last].type === "whitespace-token") last--;
|
|
3150
|
+
return w.tokens[last].endIndex;
|
|
3151
|
+
}
|
|
3152
|
+
function declarationEnd(w, item) {
|
|
3153
|
+
let last = item.end - 1;
|
|
3154
|
+
if (w.tokens[last].type === "semicolon-token") return w.tokens[last].endIndex;
|
|
3155
|
+
while (last > item.start && isInertToken(w.tokens[last])) last--;
|
|
3156
|
+
return w.tokens[last].endIndex;
|
|
3157
|
+
}
|
|
3158
|
+
function isInertToken(token) {
|
|
3159
|
+
return token.type === "whitespace-token" || token.type === "comment";
|
|
3160
|
+
}
|
|
3161
|
+
function repositionDiagnostics(diagnostics, item, span) {
|
|
3162
|
+
const preludeOffset = item.preludeOffset ?? 0;
|
|
3163
|
+
return diagnostics.map((d) => {
|
|
3164
|
+
if (d.code === "unknown-atom" || d.code === "bad-token") {
|
|
3165
|
+
return { ...d, offset: preludeOffset + d.offset, endOffset: preludeOffset + d.endOffset };
|
|
3166
|
+
}
|
|
3167
|
+
return { ...d, offset: span.start, endOffset: span.end };
|
|
3168
|
+
});
|
|
3169
|
+
}
|
|
3170
|
+
function applyExpand(w, plan2, itemOf) {
|
|
3171
|
+
const item = itemOf[plan2.ref];
|
|
3172
|
+
const span = { start: w.tokens[item.start].startIndex, end: significantEnd(w, item) };
|
|
3173
|
+
const diagnostics = repositionDiagnostics(plan2.diagnostics, item, span);
|
|
3174
|
+
if (item.blockStart !== void 0) {
|
|
3175
|
+
diagnostics.push({ code: "has-block", offset: span.start, endOffset: span.end });
|
|
3176
|
+
}
|
|
3177
|
+
w.diagnostics.push(...diagnostics);
|
|
3178
|
+
const text = renderEmissions(plan2.emissions);
|
|
3179
|
+
const source = w.positionAt(span.start);
|
|
3180
|
+
w.edits.push({
|
|
3181
|
+
start: span.start,
|
|
3182
|
+
end: span.end,
|
|
3183
|
+
parts: text === "" ? [] : [{ text, source }]
|
|
3184
|
+
});
|
|
3185
|
+
}
|
|
3186
|
+
function applyWrap(w, plan2, facts) {
|
|
3187
|
+
const first = facts.model.itemOf[plan2.refs[0]];
|
|
3188
|
+
const last = facts.model.itemOf[plan2.refs.at(-1)];
|
|
3189
|
+
const directive = facts.model.itemOf[plan2.after];
|
|
3190
|
+
const source = w.positionAt(w.tokens[directive.start].startIndex);
|
|
3191
|
+
const open = w.tokens[first.start].startIndex;
|
|
3192
|
+
w.edits.push({ start: open, end: open, parts: [{ text: "& { ", source }] });
|
|
3193
|
+
if (!facts.isClosed && last === facts.items.at(-1)) {
|
|
3194
|
+
facts.endParts.push({ text: " }", source });
|
|
3195
|
+
return;
|
|
3196
|
+
}
|
|
3197
|
+
const close = declarationEnd(w, last);
|
|
3198
|
+
w.edits.push({ start: close, end: close, parts: [{ text: " }", source }] });
|
|
3199
|
+
}
|
|
3200
|
+
function applyItem(w, plan2, facts) {
|
|
3201
|
+
if (plan2.kind === "expand") applyExpand(w, plan2, facts.model.itemOf);
|
|
3202
|
+
else if (plan2.kind === "wrap") applyWrap(w, plan2, facts);
|
|
3203
|
+
}
|
|
3204
|
+
function recordWarnings(w, warnings, itemOf) {
|
|
3205
|
+
for (const { anchor, text } of warnings) {
|
|
3206
|
+
const item = itemOf[anchor.ref];
|
|
3207
|
+
const start = anchor.offset === void 0 ? w.tokens[item.start].startIndex : (item.preludeOffset ?? 0) + anchor.offset;
|
|
3208
|
+
w.warnings.push({ offset: start, text });
|
|
3209
|
+
}
|
|
3210
|
+
}
|
|
3211
|
+
function applyRuleFrame(w, facts) {
|
|
3212
|
+
let plan2;
|
|
3213
|
+
try {
|
|
3214
|
+
plan2 = planRule({
|
|
3215
|
+
selector: facts.selector,
|
|
3216
|
+
nodes: facts.model.nodes,
|
|
3217
|
+
isInsideKeyframes: facts.isInsideKeyframes,
|
|
3218
|
+
extend: w.options.extend,
|
|
3219
|
+
reportStaleMarkers: w.options.reportStaleMarkers,
|
|
3220
|
+
emittedCache: w.emittedCache,
|
|
3221
|
+
outward: { identityOf: (ref) => facts.model.itemOf[ref].start, known: w.outwardKnown }
|
|
3222
|
+
});
|
|
3223
|
+
} catch (error) {
|
|
3224
|
+
throw error instanceof DirectiveFailure ? error.cause : error;
|
|
3225
|
+
}
|
|
3226
|
+
for (const finding of plan2.outwardFindings) {
|
|
3227
|
+
const key = facts.model.itemOf[finding.unit.directive.ref].start;
|
|
3228
|
+
w.outwardKnown.set(key, [...w.outwardKnown.get(key) ?? [], finding]);
|
|
3229
|
+
}
|
|
3230
|
+
recordWarnings(w, plan2.warnings, facts.model.itemOf);
|
|
3231
|
+
for (const item of plan2.items) applyItem(w, item, facts);
|
|
3232
|
+
}
|
|
3233
|
+
|
|
3234
|
+
// src/directive/group-at-rules.ts
|
|
3235
|
+
var WORKAROUND_GROUP_AT_RULE_NAMES = /* @__PURE__ */ new Set([
|
|
3236
|
+
"container",
|
|
3237
|
+
"layer",
|
|
3238
|
+
"media",
|
|
3239
|
+
"scope",
|
|
3240
|
+
"starting-style",
|
|
3241
|
+
"supports"
|
|
3242
|
+
]);
|
|
3243
|
+
|
|
3244
|
+
// src/directive/expand-text-context.ts
|
|
3245
|
+
function isKeyframesName(name) {
|
|
3246
|
+
return /keyframes$/i.test(name);
|
|
3247
|
+
}
|
|
3248
|
+
function childContext(source, item, context) {
|
|
3249
|
+
const { isInsideKeyframes, hasStyleRuleAncestor } = context;
|
|
3250
|
+
const { css, tokens } = source;
|
|
3251
|
+
if (item.kind === "rule") {
|
|
3252
|
+
const selectorEnd = tokens[item.blockStart - 1].startIndex;
|
|
3253
|
+
return {
|
|
3254
|
+
isStyleRuleParent: true,
|
|
3255
|
+
isInsideKeyframes,
|
|
3256
|
+
hasStyleRuleAncestor: true,
|
|
3257
|
+
isWorkaroundGroup: false,
|
|
3258
|
+
selector: css.slice(tokens[item.start].startIndex, selectorEnd).trim()
|
|
3259
|
+
};
|
|
3260
|
+
}
|
|
3261
|
+
const name = atKeywordName(tokens[item.start]);
|
|
3262
|
+
const isKeyframes = isInsideKeyframes || isKeyframesName(name);
|
|
3263
|
+
return {
|
|
3264
|
+
isStyleRuleParent: false,
|
|
3265
|
+
isInsideKeyframes: isKeyframes,
|
|
3266
|
+
hasStyleRuleAncestor,
|
|
3267
|
+
isWorkaroundGroup: WORKAROUND_GROUP_AT_RULE_NAMES.has(name) && !isKeyframes && hasStyleRuleAncestor,
|
|
3268
|
+
selector: ""
|
|
3269
|
+
};
|
|
3270
|
+
}
|
|
3271
|
+
|
|
3272
|
+
// src/directive/expand-text-terminator.ts
|
|
3273
|
+
function endOfToken(tokens, lastAt, limit) {
|
|
3274
|
+
const last = tokens[lastAt];
|
|
3275
|
+
const isLoneBackslash = last.type === "delim-token" && last.raw === "\\";
|
|
3276
|
+
return isLoneBackslash && lastAt + 1 < limit ? tokens[lastAt + 1].endIndex : last.endIndex;
|
|
3277
|
+
}
|
|
3278
|
+
|
|
3279
|
+
// src/directive/expand-text-eof-close.ts
|
|
3280
|
+
function hasUnescapedTrailingChar(raw, char) {
|
|
3281
|
+
if (raw.length < 2 || raw.at(-1) !== char) return false;
|
|
3282
|
+
let backslashes = 0;
|
|
3283
|
+
for (let i = raw.length - 2; i >= 0 && raw[i] === "\\"; i--) backslashes++;
|
|
3284
|
+
return backslashes % 2 === 0;
|
|
3285
|
+
}
|
|
3286
|
+
function trailingBackslashCount(raw) {
|
|
3287
|
+
let count = 0;
|
|
3288
|
+
for (let i = raw.length - 1; i >= 0 && raw[i] === "\\"; i--) count++;
|
|
3289
|
+
return count;
|
|
3290
|
+
}
|
|
3291
|
+
var ESCAPE_CLOSER = "fffd";
|
|
3292
|
+
function isStringEndingInLoneBackslash(token) {
|
|
3293
|
+
return token.type === "string-token" && !hasUnescapedTrailingChar(token.raw, token.raw[0] ?? "") && trailingBackslashCount(token.raw) % 2 === 1;
|
|
3294
|
+
}
|
|
3295
|
+
function lexicalEofCloser(token) {
|
|
3296
|
+
if (token.type === "string-token") {
|
|
3297
|
+
const quote = token.raw[0];
|
|
3298
|
+
if (quote === void 0 || hasUnescapedTrailingChar(token.raw, quote)) return void 0;
|
|
3299
|
+
return quote;
|
|
3300
|
+
}
|
|
3301
|
+
if (token.type === "url-token" || token.type === "bad-url-token") {
|
|
3302
|
+
if (token.raw.endsWith(")")) return void 0;
|
|
3303
|
+
return trailingBackslashCount(token.raw) % 2 === 1 ? String.raw`\)` : ")";
|
|
3304
|
+
}
|
|
3305
|
+
return trailingBackslashCount(token.raw) % 2 === 1 ? ESCAPE_CLOSER : void 0;
|
|
3306
|
+
}
|
|
3307
|
+
function bracketEofCloser(type) {
|
|
3308
|
+
if (type === "{-token") return "}";
|
|
3309
|
+
if (type === "[-token") return "]";
|
|
3310
|
+
return ")";
|
|
3311
|
+
}
|
|
3312
|
+
function scanFrameTail(w, start, limit) {
|
|
3313
|
+
const scan = { unmatchedOpeners: [], hasDanglingText: false, hasOpenColon: false };
|
|
3314
|
+
let i = start;
|
|
3315
|
+
while (i < limit) i = scanToken(w, i, limit, scan) + 1;
|
|
3316
|
+
return { ...scan, unmatchedOpeners: scan.unmatchedOpeners.toReversed() };
|
|
3317
|
+
}
|
|
3318
|
+
function scanToken(w, i, limit, scan) {
|
|
3319
|
+
const type = w.tokens[i].type;
|
|
3320
|
+
if (type !== "whitespace-token" && type !== "comment") scan.hasDanglingText = true;
|
|
3321
|
+
if (type === "semicolon-token") {
|
|
3322
|
+
scan.hasOpenColon = false;
|
|
3323
|
+
scan.hasDanglingText = false;
|
|
3324
|
+
} else if (type === "colon-token") {
|
|
3325
|
+
scan.hasOpenColon = true;
|
|
3326
|
+
} else if (OPENERS.has(type)) {
|
|
3327
|
+
const closeIndex = w.closerFor[i];
|
|
3328
|
+
if (closeIndex === -1 || closeIndex >= limit) {
|
|
3329
|
+
scan.unmatchedOpeners.push(i);
|
|
3330
|
+
return i;
|
|
3331
|
+
}
|
|
3332
|
+
if (type === "{-token") scan.hasDanglingText = false;
|
|
3333
|
+
return closeIndex;
|
|
3334
|
+
}
|
|
3335
|
+
return i;
|
|
3336
|
+
}
|
|
3337
|
+
function eofClosers(w, start, limit, last) {
|
|
3338
|
+
const closers = [];
|
|
3339
|
+
const lexical = last ? lexicalEofCloser(last) : void 0;
|
|
3340
|
+
if (lexical) closers.push(lexical);
|
|
3341
|
+
const scan = scanFrameTail(w, start, limit);
|
|
3342
|
+
for (const openIndex of scan.unmatchedOpeners) {
|
|
3343
|
+
closers.push(bracketEofCloser(w.tokens[openIndex].type));
|
|
3344
|
+
}
|
|
3345
|
+
if (scan.hasOpenColon) {
|
|
3346
|
+
closers.push(";");
|
|
3347
|
+
} else if (closers.length === (lexical === ESCAPE_CLOSER ? 1 : 0) && scan.hasDanglingText) {
|
|
3348
|
+
closers.push("{}");
|
|
3349
|
+
}
|
|
3350
|
+
return closers.join("");
|
|
3351
|
+
}
|
|
3352
|
+
function closeInfoFor(w, frameStart, blockEndIndex, scanLimit) {
|
|
3353
|
+
const closer = w.tokens[blockEndIndex];
|
|
3354
|
+
if (closer) return { position: closer.startIndex, prefix: "", prefixPosition: closer.startIndex };
|
|
3355
|
+
const last = scanLimit > frameStart ? w.tokens[scanLimit - 1] : void 0;
|
|
3356
|
+
const trailing = unclosedTrailingComment(w);
|
|
3357
|
+
if (trailing !== void 0 && last !== trailing) {
|
|
3358
|
+
const prefix2 = eofClosers(w, frameStart, scanLimit, last);
|
|
3359
|
+
return { position: trailing.startIndex, prefix: prefix2, prefixPosition: trailing.startIndex };
|
|
3360
|
+
}
|
|
3361
|
+
if (last?.type === "comment") {
|
|
3362
|
+
const position = isClosedComment(last) ? w.css.length : last.startIndex;
|
|
3363
|
+
return { position, ...closersBeforeComment(w, frameStart, scanLimit, position) };
|
|
3364
|
+
}
|
|
3365
|
+
const prefix = eofClosers(w, frameStart, scanLimit, last);
|
|
3366
|
+
if (last !== void 0 && isStringEndingInLoneBackslash(last)) {
|
|
3367
|
+
const position = last.endIndex - 1;
|
|
3368
|
+
return { position, prefix, prefixPosition: position };
|
|
3369
|
+
}
|
|
3370
|
+
return { position: w.css.length, prefix, prefixPosition: w.css.length };
|
|
3371
|
+
}
|
|
3372
|
+
function isClosedComment(token) {
|
|
3373
|
+
return token.raw.length >= 4 && token.raw.endsWith("*/");
|
|
3374
|
+
}
|
|
3375
|
+
function unclosedTrailingComment(w) {
|
|
3376
|
+
const token = w.tokens.at(-1);
|
|
3377
|
+
return token?.type === "comment" && !isClosedComment(token) ? token : void 0;
|
|
3378
|
+
}
|
|
3379
|
+
function isInert(token) {
|
|
3380
|
+
return token.type === "whitespace-token" || token.type === "comment";
|
|
3381
|
+
}
|
|
3382
|
+
function closersBeforeComment(w, frameStart, scanLimit, fallback) {
|
|
3383
|
+
let i = scanLimit - 1;
|
|
3384
|
+
while (i >= frameStart && isInert(w.tokens[i])) i--;
|
|
3385
|
+
if (i < frameStart) return { prefix: "", prefixPosition: fallback };
|
|
3386
|
+
return {
|
|
3387
|
+
prefix: eofClosers(w, frameStart, scanLimit, void 0),
|
|
3388
|
+
prefixPosition: endOfToken(w.tokens, i, scanLimit)
|
|
3389
|
+
};
|
|
3390
|
+
}
|
|
3391
|
+
|
|
3392
|
+
// src/directive/expand-text-model.ts
|
|
3393
|
+
var GROUP_NAMES2 = /* @__PURE__ */ new Set(["container", "media", "supports"]);
|
|
3394
|
+
function isInert2(token) {
|
|
3395
|
+
return token.type === "whitespace-token" || token.type === "comment";
|
|
3396
|
+
}
|
|
3397
|
+
function readBlockItems(source, start, limit) {
|
|
3398
|
+
const items = [];
|
|
3399
|
+
let i = start;
|
|
3400
|
+
while (i < limit) {
|
|
3401
|
+
if (isInert2(source.tokens[i])) {
|
|
3402
|
+
i++;
|
|
3403
|
+
continue;
|
|
3404
|
+
}
|
|
3405
|
+
const item = readItem(source.tokens, i, limit, source.closerFor);
|
|
3406
|
+
items.push(item);
|
|
3407
|
+
i = item.end;
|
|
3408
|
+
}
|
|
3409
|
+
return items;
|
|
3410
|
+
}
|
|
3411
|
+
function colonIndex(tokens, item) {
|
|
3412
|
+
let i = item.start + 1;
|
|
3413
|
+
while (i < item.end && tokens[i].type !== "colon-token") i++;
|
|
3414
|
+
return i;
|
|
3415
|
+
}
|
|
3416
|
+
function valueEndIndex(tokens, item) {
|
|
3417
|
+
const last = tokens[item.end - 1];
|
|
3418
|
+
return last?.type === "semicolon-token" ? item.end - 1 : item.end;
|
|
3419
|
+
}
|
|
3420
|
+
function lastSignificant2(tokens, from, to) {
|
|
3421
|
+
let i = to - 1;
|
|
3422
|
+
while (i >= from && isInert2(tokens[i])) i--;
|
|
3423
|
+
return i;
|
|
3424
|
+
}
|
|
3425
|
+
function isImportantIdent(token) {
|
|
3426
|
+
return token?.type === "ident-token" && String(token.structured?.value).toLowerCase() === "important";
|
|
3427
|
+
}
|
|
3428
|
+
function importantIndex(tokens, from, to) {
|
|
3429
|
+
const ident = lastSignificant2(tokens, from, to);
|
|
3430
|
+
if (!isImportantIdent(tokens[ident])) return void 0;
|
|
3431
|
+
const bang = lastSignificant2(tokens, from, ident);
|
|
3432
|
+
const token = tokens[bang];
|
|
3433
|
+
return token?.type === "delim-token" && token.structured?.value === "!" ? bang : void 0;
|
|
3434
|
+
}
|
|
3435
|
+
function trimmedText(source, from, to) {
|
|
3436
|
+
let start = from;
|
|
3437
|
+
let end = to;
|
|
3438
|
+
while (start < end && isInert2(source.tokens[start])) start++;
|
|
3439
|
+
while (end > start && isInert2(source.tokens[end - 1])) end--;
|
|
3440
|
+
if (start >= end) return "";
|
|
3441
|
+
return source.css.slice(source.tokens[start].startIndex, source.tokens[end - 1].endIndex);
|
|
3442
|
+
}
|
|
3443
|
+
function declarationNode2(source, item, ref) {
|
|
3444
|
+
const { tokens } = source;
|
|
3445
|
+
const colon = colonIndex(tokens, item);
|
|
3446
|
+
const end = valueEndIndex(tokens, item);
|
|
3447
|
+
const bang = importantIndex(tokens, colon + 1, end);
|
|
3448
|
+
return {
|
|
3449
|
+
kind: "decl",
|
|
3450
|
+
ref,
|
|
3451
|
+
prop: String(tokens[item.start].structured?.value),
|
|
3452
|
+
value: trimmedText(source, colon + 1, bang ?? end),
|
|
3453
|
+
important: bang !== void 0
|
|
3454
|
+
};
|
|
3455
|
+
}
|
|
3456
|
+
function selectorOf(source, item) {
|
|
3457
|
+
return trimmedText(source, item.start, item.blockStart - 1);
|
|
3458
|
+
}
|
|
3459
|
+
function usable(items) {
|
|
3460
|
+
return items.filter((item) => item.kind !== "invalid");
|
|
3461
|
+
}
|
|
3462
|
+
function contentOf(source, item, itemOf) {
|
|
3463
|
+
let nodes;
|
|
3464
|
+
return () => {
|
|
3465
|
+
nodes ??= readItems(source, readBlockItems(source, item.blockStart, item.blockEnd), itemOf);
|
|
3466
|
+
return nodes;
|
|
3467
|
+
};
|
|
3468
|
+
}
|
|
3469
|
+
function ruleNode(source, item, ref, itemOf) {
|
|
3470
|
+
const content = contentOf(source, item, itemOf);
|
|
3471
|
+
return {
|
|
3472
|
+
kind: "rule",
|
|
3473
|
+
ref,
|
|
3474
|
+
selector: selectorOf(source, item),
|
|
3475
|
+
get nodes() {
|
|
3476
|
+
return content();
|
|
3477
|
+
}
|
|
3478
|
+
};
|
|
3479
|
+
}
|
|
3480
|
+
function atRuleNode(source, item, ref, itemOf) {
|
|
3481
|
+
const prelude = source.css.slice(item.preludeOffset ?? 0, item.preludeEndOffset ?? 0);
|
|
3482
|
+
if (isNaveAtKeyword(source.tokens[item.start])) return { kind: "directive", ref, prelude };
|
|
3483
|
+
const name = item.atKeyword ?? "";
|
|
3484
|
+
if (!GROUP_NAMES2.has(name) || item.blockStart === void 0) {
|
|
3485
|
+
return { kind: "opaque", ref, name, prelude: prelude.trim() };
|
|
3486
|
+
}
|
|
3487
|
+
const content = contentOf(source, item, itemOf);
|
|
3488
|
+
return {
|
|
3489
|
+
kind: "group",
|
|
3490
|
+
ref,
|
|
3491
|
+
name,
|
|
3492
|
+
prelude: prelude.trim(),
|
|
3493
|
+
get nodes() {
|
|
3494
|
+
return content();
|
|
3495
|
+
}
|
|
3496
|
+
};
|
|
3497
|
+
}
|
|
3498
|
+
function itemNode(source, item, ref, itemOf) {
|
|
3499
|
+
if (item.kind === "declaration") return declarationNode2(source, item, ref);
|
|
3500
|
+
if (item.kind === "rule" && item.blockStart !== void 0) {
|
|
3501
|
+
return ruleNode(source, item, ref, itemOf);
|
|
3502
|
+
}
|
|
3503
|
+
if (item.kind === "at-rule") return atRuleNode(source, item, ref, itemOf);
|
|
3504
|
+
return { kind: "opaque", ref, name: "", prelude: "" };
|
|
3505
|
+
}
|
|
3506
|
+
function readItems(source, items, itemOf) {
|
|
3507
|
+
return usable(items).map((item) => {
|
|
3508
|
+
const ref = itemOf.length;
|
|
3509
|
+
itemOf.push(item);
|
|
3510
|
+
return itemNode(source, item, ref, itemOf);
|
|
3511
|
+
});
|
|
3512
|
+
}
|
|
3513
|
+
function readBlockModel(source, items) {
|
|
3514
|
+
const itemOf = [];
|
|
3515
|
+
const nodes = readItems(source, items, itemOf);
|
|
3516
|
+
return { nodes, itemOf };
|
|
3517
|
+
}
|
|
3518
|
+
|
|
3519
|
+
// src/directive/expand-text-walk.ts
|
|
3520
|
+
var Walker = class {
|
|
3521
|
+
closerFor;
|
|
3522
|
+
css;
|
|
3523
|
+
diagnostics = [];
|
|
3524
|
+
// The index of every `@nave` token, in order: whether a block holds a directive anywhere inside.
|
|
3525
|
+
directiveTokens;
|
|
3526
|
+
edits = [];
|
|
3527
|
+
emittedCache = /* @__PURE__ */ new Map();
|
|
3528
|
+
// Built once per call, not once per query: `positionAt` runs once per
|
|
3529
|
+
// output token, and a fresh linear scan on every call made the whole
|
|
3530
|
+
// pass quadratic in the stylesheet's size. Not private: this
|
|
3531
|
+
// project's class-member-order and class-sort lint rules disagree with
|
|
3532
|
+
// each other on where a private field goes relative to the surrounding
|
|
3533
|
+
// public ones, which a field with no access modifier sidesteps.
|
|
3534
|
+
// How far back an EOF-closing frame may look for its own unmatched
|
|
3535
|
+
// brackets/declaration: shrinks to a frame's own start every time that
|
|
3536
|
+
// frame writes its own EOF closers, so an ancestor frame further out
|
|
3537
|
+
// never rediscovers — and re-closes — the same inner construct. Starts
|
|
3538
|
+
// at `tokens.length`, unbounded, since nothing has closed anything yet.
|
|
3539
|
+
eofScanLimit;
|
|
3540
|
+
findPosition;
|
|
3541
|
+
options;
|
|
3542
|
+
// What an enclosing rule found for a directive written in a rule nested in it, by the directive's
|
|
3543
|
+
// first token, for the plan of that rule.
|
|
3544
|
+
outwardKnown = /* @__PURE__ */ new Map();
|
|
3545
|
+
tokens;
|
|
3546
|
+
warnings = [];
|
|
3547
|
+
constructor(css, options) {
|
|
3548
|
+
this.css = css;
|
|
3549
|
+
this.tokens = tokenize(css);
|
|
3550
|
+
this.closerFor = matchBrackets(this.tokens);
|
|
3551
|
+
this.options = options;
|
|
3552
|
+
this.findPosition = createPositionFinder(css);
|
|
3553
|
+
this.eofScanLimit = this.tokens.length;
|
|
3554
|
+
this.directiveTokens = this.tokens.flatMap(
|
|
3555
|
+
(token, index) => isNaveAtKeyword(token) ? [index] : []
|
|
3556
|
+
);
|
|
3557
|
+
}
|
|
3558
|
+
/**
|
|
3559
|
+
* Whether a `@nave` stands between the tokens `start` and `limit`, at any depth.
|
|
3560
|
+
*/
|
|
3561
|
+
hasDirectiveWithin(start, limit) {
|
|
3562
|
+
let low = 0;
|
|
3563
|
+
let high = this.directiveTokens.length;
|
|
3564
|
+
while (low < high) {
|
|
3565
|
+
const middle = low + high >> 1;
|
|
3566
|
+
if (this.directiveTokens[middle] <= start) low = middle + 1;
|
|
3567
|
+
else high = middle;
|
|
3568
|
+
}
|
|
3569
|
+
const next = this.directiveTokens[low];
|
|
3570
|
+
return next !== void 0 && next < limit;
|
|
3571
|
+
}
|
|
3572
|
+
positionAt(offset) {
|
|
3573
|
+
return this.findPosition(offset);
|
|
3574
|
+
}
|
|
3575
|
+
};
|
|
3576
|
+
function markNestedGroup(diagnostics) {
|
|
3577
|
+
for (const [i, d] of diagnostics.entries()) {
|
|
3578
|
+
if (d.code === "bad-parent") diagnostics[i] = { ...d, detail: "nested-group" };
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
function processRefusedDirective(w, item, context) {
|
|
3582
|
+
const directiveStart = w.tokens[item.start].startIndex;
|
|
3583
|
+
const directiveEnd = w.tokens[item.end - 1].endIndex;
|
|
3584
|
+
const prelude = w.css.slice(item.preludeOffset ?? 0, item.preludeEndOffset ?? 0);
|
|
3585
|
+
const result = plan(
|
|
3586
|
+
prelude,
|
|
3587
|
+
{ isStyleRuleParent: false, isInsideKeyframes: context.isInsideKeyframes },
|
|
3588
|
+
{ extend: w.options.extend }
|
|
3589
|
+
);
|
|
3590
|
+
const positioned = repositionDiagnostics(result.diagnostics, item, {
|
|
3591
|
+
start: directiveStart,
|
|
3592
|
+
end: directiveEnd
|
|
3593
|
+
});
|
|
3594
|
+
if (context.isWorkaroundGroup) markNestedGroup(positioned);
|
|
3595
|
+
if (item.blockStart !== void 0)
|
|
3596
|
+
positioned.push({ code: "has-block", offset: directiveStart, endOffset: directiveEnd });
|
|
3597
|
+
w.diagnostics.push(...positioned);
|
|
3598
|
+
w.edits.push({ start: directiveStart, end: directiveEnd, parts: [] });
|
|
3599
|
+
}
|
|
3600
|
+
function flushFrame(w, frameStart, blockEndIndex, frame) {
|
|
3601
|
+
if (frame.parts.length === 0) return;
|
|
3602
|
+
const close = closeInfoFor(w, frameStart, blockEndIndex, w.eofScanLimit);
|
|
3603
|
+
if (w.tokens[blockEndIndex] === void 0) w.eofScanLimit = frameStart;
|
|
3604
|
+
if (close.prefix !== "") {
|
|
3605
|
+
const source = w.positionAt(close.prefixPosition);
|
|
3606
|
+
w.edits.push({
|
|
3607
|
+
start: close.prefixPosition,
|
|
3608
|
+
end: close.prefixPosition,
|
|
3609
|
+
parts: [{ text: close.prefix, source }]
|
|
3610
|
+
});
|
|
3611
|
+
}
|
|
3612
|
+
w.edits.push({ start: close.position, end: close.position, parts: frame.parts });
|
|
3613
|
+
}
|
|
3614
|
+
function isDirective(w, item) {
|
|
3615
|
+
return item.kind === "at-rule" && isNaveAtKeyword(w.tokens[item.start]);
|
|
3616
|
+
}
|
|
3617
|
+
function hasDirectiveInside(w, items, bounds) {
|
|
3618
|
+
return items.some((item) => isDirective(w, item)) || w.hasDirectiveWithin(bounds.start, bounds.limit);
|
|
3619
|
+
}
|
|
3620
|
+
function toWalkFrame(w, bounds) {
|
|
3621
|
+
const items = readBlockItems(w, bounds.start, bounds.limit);
|
|
3622
|
+
const frame = { parts: [] };
|
|
3623
|
+
if (bounds.context.isStyleRuleParent && hasDirectiveInside(w, items, bounds)) {
|
|
3624
|
+
applyRuleFrame(w, {
|
|
3625
|
+
items,
|
|
3626
|
+
model: readBlockModel(w, items),
|
|
3627
|
+
selector: bounds.context.selector,
|
|
3628
|
+
isInsideKeyframes: bounds.context.isInsideKeyframes,
|
|
3629
|
+
isClosed: w.tokens[bounds.limit] !== void 0,
|
|
3630
|
+
endParts: frame.parts
|
|
3631
|
+
});
|
|
3632
|
+
}
|
|
3633
|
+
return {
|
|
3634
|
+
next: 0,
|
|
3635
|
+
items,
|
|
3636
|
+
limit: bounds.limit,
|
|
3637
|
+
start: bounds.start,
|
|
3638
|
+
context: bounds.context,
|
|
3639
|
+
frame
|
|
3640
|
+
};
|
|
3641
|
+
}
|
|
3642
|
+
function childFrameFor(w, item, context) {
|
|
3643
|
+
if (item.blockStart === void 0 || item.blockEnd === void 0) return void 0;
|
|
3644
|
+
return toWalkFrame(w, {
|
|
3645
|
+
start: item.blockStart,
|
|
3646
|
+
limit: item.blockEnd,
|
|
3647
|
+
context: childContext(w, item, context)
|
|
3648
|
+
});
|
|
3649
|
+
}
|
|
3650
|
+
function walkBlock(w, bounds) {
|
|
3651
|
+
const stack = [toWalkFrame(w, bounds)];
|
|
3652
|
+
while (stack.length > 0) {
|
|
3653
|
+
const top = stack.at(-1);
|
|
3654
|
+
const item = top.items[top.next];
|
|
3655
|
+
if (item === void 0) {
|
|
3656
|
+
flushFrame(w, top.start, top.limit, top.frame);
|
|
3657
|
+
stack.pop();
|
|
3658
|
+
continue;
|
|
3659
|
+
}
|
|
3660
|
+
top.next++;
|
|
3661
|
+
if (isDirective(w, item)) {
|
|
3662
|
+
if (!top.context.isStyleRuleParent) processRefusedDirective(w, item, top.context);
|
|
3663
|
+
} else if (item.kind === "rule" || item.kind === "at-rule") {
|
|
3664
|
+
const child = childFrameFor(w, item, top.context);
|
|
3665
|
+
if (child) stack.push(child);
|
|
3666
|
+
}
|
|
3667
|
+
}
|
|
3668
|
+
}
|
|
3669
|
+
|
|
3670
|
+
// src/directive/expand-text.ts
|
|
3671
|
+
function expandText(css, options = {}) {
|
|
3672
|
+
const w = new Walker(css, options);
|
|
3673
|
+
walkBlock(w, {
|
|
3674
|
+
start: 0,
|
|
3675
|
+
limit: w.tokens.length,
|
|
3676
|
+
context: {
|
|
3677
|
+
isStyleRuleParent: false,
|
|
3678
|
+
isInsideKeyframes: false,
|
|
3679
|
+
hasStyleRuleAncestor: false,
|
|
3680
|
+
isWorkaroundGroup: false,
|
|
3681
|
+
selector: ""
|
|
3682
|
+
}
|
|
3683
|
+
});
|
|
3684
|
+
const { css: outputCss, map } = buildOutput({
|
|
3685
|
+
css: w.css,
|
|
3686
|
+
tokens: w.tokens,
|
|
3687
|
+
edits: w.edits,
|
|
3688
|
+
from: options.from,
|
|
3689
|
+
inputSourceMap: options.inputSourceMap,
|
|
3690
|
+
positionAt: (offset) => w.positionAt(offset)
|
|
3691
|
+
});
|
|
3692
|
+
return {
|
|
3693
|
+
css: outputCss,
|
|
3694
|
+
map,
|
|
3695
|
+
diagnostics: reportDiagnostics(w.diagnostics, css, options),
|
|
3696
|
+
warnings: positionWarnings(w.warnings, css, options.from)
|
|
3697
|
+
};
|
|
3698
|
+
}
|
|
3699
|
+
|
|
3700
|
+
// src/snapshot-extend-atoms.ts
|
|
3701
|
+
function snapshotDeclarations(declarations) {
|
|
3702
|
+
if (!isPlainObject(declarations)) return declarations;
|
|
3703
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
3704
|
+
for (const [prop, value] of Object.entries(declarations)) {
|
|
3705
|
+
out[prop] = typeof value === "string" ? value : String(value);
|
|
3706
|
+
}
|
|
3707
|
+
return out;
|
|
3708
|
+
}
|
|
3709
|
+
function snapshotPseudos(pseudos) {
|
|
3710
|
+
if (!isPlainObject(pseudos)) return pseudos;
|
|
3711
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
3712
|
+
for (const [selector, declarations] of Object.entries(pseudos)) {
|
|
3713
|
+
out[selector] = snapshotDeclarations(declarations);
|
|
3714
|
+
}
|
|
3715
|
+
return out;
|
|
3716
|
+
}
|
|
3717
|
+
function snapshotAtBlock(block) {
|
|
3718
|
+
if (!isPlainObject(block)) return block;
|
|
3719
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
3720
|
+
if ("declarations" in block) out.declarations = snapshotDeclarations(block.declarations);
|
|
3721
|
+
if ("pseudos" in block) out.pseudos = snapshotPseudos(block.pseudos);
|
|
3722
|
+
return out;
|
|
3723
|
+
}
|
|
3724
|
+
function snapshotAtBlocks(blocks) {
|
|
3725
|
+
if (!isPlainObject(blocks)) return blocks;
|
|
3726
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
3727
|
+
for (const [condition, block] of Object.entries(blocks)) {
|
|
3728
|
+
out[condition] = snapshotAtBlock(block);
|
|
3729
|
+
}
|
|
3730
|
+
return out;
|
|
3731
|
+
}
|
|
3732
|
+
function snapshotAtomDefinition(atom) {
|
|
3733
|
+
if (!isPlainObject(atom)) return atom;
|
|
3734
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
3735
|
+
if ("declarations" in atom) out.declarations = snapshotDeclarations(atom.declarations);
|
|
3736
|
+
if ("pseudos" in atom) out.pseudos = snapshotPseudos(atom.pseudos);
|
|
3737
|
+
if ("media" in atom) out.media = snapshotAtBlocks(atom.media);
|
|
3738
|
+
if ("container" in atom) out.container = snapshotAtBlocks(atom.container);
|
|
3739
|
+
return out;
|
|
3740
|
+
}
|
|
3741
|
+
function snapshotExtendMap(map) {
|
|
3742
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
3743
|
+
for (const [name, atom] of Object.entries(map)) {
|
|
3744
|
+
out[name] = snapshotAtomDefinition(atom);
|
|
3745
|
+
}
|
|
3746
|
+
return out;
|
|
3747
|
+
}
|
|
3748
|
+
|
|
3749
|
+
// src/directive/fold.ts
|
|
3750
|
+
function splitAvailable(text) {
|
|
3751
|
+
const lines = text.split("\n");
|
|
3752
|
+
const last = lines.at(-1);
|
|
3753
|
+
if (lines.length > 1 && last?.startsWith("Available: ")) {
|
|
3754
|
+
return { body: lines.slice(0, -1).join("\n"), available: last };
|
|
3755
|
+
}
|
|
3756
|
+
return { body: text, available: void 0 };
|
|
3757
|
+
}
|
|
3758
|
+
function withoutNavePrefix(text) {
|
|
3759
|
+
return text.startsWith("@nave: ") ? text.slice(7) : text;
|
|
3760
|
+
}
|
|
3761
|
+
function foldLocated(entries) {
|
|
3762
|
+
const parts = entries.map((entry) => ({ ...splitAvailable(entry.text), entry }));
|
|
3763
|
+
const [first, ...rest] = parts;
|
|
3764
|
+
const lines = [first.body];
|
|
3765
|
+
if (rest.length > 0) {
|
|
3766
|
+
lines.push(`${rest.length} more in this stylesheet:`);
|
|
3767
|
+
for (const { body, entry } of rest) {
|
|
3768
|
+
lines.push(`${entry.line}:${entry.column}: ${withoutNavePrefix(body)}`);
|
|
3769
|
+
}
|
|
3770
|
+
}
|
|
3771
|
+
const available = parts.find((part) => part.available !== void 0)?.available;
|
|
3772
|
+
if (available) lines.push(available);
|
|
3773
|
+
return lines.join("\n");
|
|
3774
|
+
}
|
|
3775
|
+
|
|
3776
|
+
// src/validate-extend-scan.ts
|
|
3777
|
+
function isInert3(token) {
|
|
3778
|
+
return token.type === "whitespace-token" || token.type === "comment";
|
|
3779
|
+
}
|
|
3780
|
+
function isOnlyInert(tokens, from, to) {
|
|
3781
|
+
for (let i = from; i < to; i++) if (!isInert3(tokens[i])) return false;
|
|
3782
|
+
return true;
|
|
3783
|
+
}
|
|
3784
|
+
function hasStrayCurlyCloser(wrapped, from, to) {
|
|
3785
|
+
const matchedClosers = new Set(wrapped.closerFor);
|
|
3786
|
+
for (let i = from; i < to; i++) {
|
|
3787
|
+
if (wrapped.tokens[i].type === "}-token" && !matchedClosers.has(i)) return true;
|
|
3788
|
+
}
|
|
3789
|
+
return false;
|
|
3790
|
+
}
|
|
3791
|
+
function hasPaddedComment(tokens, from, to) {
|
|
3792
|
+
for (let i = from; i < to; i++) {
|
|
3793
|
+
if (tokens[i].type !== "comment") continue;
|
|
3794
|
+
if (tokens[i - 1]?.type === "whitespace-token" || tokens[i + 1]?.type === "whitespace-token")
|
|
3795
|
+
return true;
|
|
3796
|
+
}
|
|
3797
|
+
return false;
|
|
3798
|
+
}
|
|
3799
|
+
function hasTopLevelComment(wrapped, from, to) {
|
|
3800
|
+
let i = from;
|
|
3801
|
+
while (i < to) {
|
|
3802
|
+
const closer = wrapped.closerFor[i];
|
|
3803
|
+
const type = wrapped.tokens[i].type;
|
|
3804
|
+
if (closer !== -1 && (type === "(-token" || type === "function-token")) {
|
|
3805
|
+
i = closer + 1;
|
|
3806
|
+
continue;
|
|
3807
|
+
}
|
|
3808
|
+
if (type === "comment") return true;
|
|
3809
|
+
i++;
|
|
3810
|
+
}
|
|
3811
|
+
return false;
|
|
3812
|
+
}
|
|
3813
|
+
function hasBrokenString(tokens, from, to) {
|
|
3814
|
+
for (let i = from; i < to; i++) {
|
|
3815
|
+
if (tokens[i].type === "bad-string-token" || tokens[i].type === "bad-url-token") return true;
|
|
3816
|
+
}
|
|
3817
|
+
return false;
|
|
3818
|
+
}
|
|
3819
|
+
function hasUrl(tokens, from, to) {
|
|
3820
|
+
for (let i = from; i < to; i++) {
|
|
3821
|
+
if (tokens[i].type === "url-token" && tokens[i].raw.includes("/*")) return true;
|
|
3822
|
+
}
|
|
3823
|
+
return false;
|
|
3824
|
+
}
|
|
3825
|
+
function lastNonWhitespace(tokens, from, to) {
|
|
3826
|
+
let i = to - 1;
|
|
3827
|
+
while (i >= from && tokens[i].type === "whitespace-token") i--;
|
|
3828
|
+
return i;
|
|
3829
|
+
}
|
|
3830
|
+
function hasTopLevelColon(wrapped, from, to) {
|
|
3831
|
+
let i = from;
|
|
3832
|
+
while (i < to) {
|
|
3833
|
+
const closer = wrapped.closerFor[i];
|
|
3834
|
+
const type = wrapped.tokens[i].type;
|
|
3835
|
+
if (closer !== -1 && (type === "(-token" || type === "function-token")) {
|
|
3836
|
+
i = closer + 1;
|
|
3837
|
+
continue;
|
|
3838
|
+
}
|
|
3839
|
+
if (wrapped.tokens[i].type === "colon-token") return true;
|
|
3840
|
+
i++;
|
|
3841
|
+
}
|
|
3842
|
+
return false;
|
|
3843
|
+
}
|
|
3844
|
+
function hasEscapedCommentOpener(text) {
|
|
3845
|
+
const outsideStrings = tokenize(text).map((token) => token.type === "string-token" ? '""' : token.raw).join("");
|
|
3846
|
+
return outsideStrings.includes(String.raw`\/*`);
|
|
3847
|
+
}
|
|
3848
|
+
function hasHtmlBreakout(text) {
|
|
3849
|
+
return /<\/?style\b/i.test(text) || text.includes("<!--");
|
|
3850
|
+
}
|
|
3851
|
+
function hasUnstrippedTrailingSpace(text) {
|
|
3852
|
+
const tokens = tokenize(text);
|
|
3853
|
+
const last = lastNonWhitespace(tokens, 0, tokens.length);
|
|
3854
|
+
const raw = tokens[last]?.raw;
|
|
3855
|
+
return raw !== void 0 && raw !== raw.trimEnd();
|
|
3856
|
+
}
|
|
3857
|
+
function hasUnstrippedLeadingSpace(text) {
|
|
3858
|
+
const tokens = tokenize(text);
|
|
3859
|
+
const first = tokens.findIndex((token) => token.type !== "whitespace-token");
|
|
3860
|
+
const raw = tokens[first]?.raw;
|
|
3861
|
+
return raw !== void 0 && raw !== raw.trimStart();
|
|
3862
|
+
}
|
|
3863
|
+
function hasEscapedWhitespace(text) {
|
|
3864
|
+
return /\\[\da-f]{0,6}[\t\n\f\r ]/i.test(text);
|
|
3865
|
+
}
|
|
3866
|
+
|
|
3867
|
+
// src/validate-extend-breakout.ts
|
|
3868
|
+
var SENTINEL = ".nave-sentinel{}";
|
|
3869
|
+
var ATOM = "probe";
|
|
3870
|
+
function atomFor(splice) {
|
|
3871
|
+
if (splice.kind === "declarations") {
|
|
3872
|
+
return { atoms: { [ATOM]: { declarations: splice.declarations } }, nested: 0 };
|
|
3873
|
+
}
|
|
3874
|
+
const color = { color: "red" };
|
|
3875
|
+
if (splice.kind === "pseudo") {
|
|
3876
|
+
const pseudos = { [splice.key]: color };
|
|
3877
|
+
return { atoms: { [ATOM]: { declarations: {}, pseudos } }, nested: 1 };
|
|
3878
|
+
}
|
|
3879
|
+
const blocks = { [splice.condition]: { declarations: color } };
|
|
3880
|
+
return { atoms: { [ATOM]: { declarations: {}, [splice.atName]: blocks } }, nested: 1 };
|
|
3881
|
+
}
|
|
3882
|
+
function itemsIn(tokens, closerFor, from, to) {
|
|
3883
|
+
const items = [];
|
|
3884
|
+
let i = from;
|
|
3885
|
+
while (i < to) {
|
|
3886
|
+
const type = tokens[i].type;
|
|
3887
|
+
if (type === "whitespace-token" || type === "comment") {
|
|
3888
|
+
i++;
|
|
3889
|
+
continue;
|
|
3890
|
+
}
|
|
3891
|
+
const item = readItem(tokens, i, to, closerFor);
|
|
3892
|
+
items.push(item);
|
|
3893
|
+
i = Math.max(item.end, i + 1);
|
|
3894
|
+
}
|
|
3895
|
+
return items;
|
|
3896
|
+
}
|
|
3897
|
+
function textOf(tokens, from, to) {
|
|
3898
|
+
return tokens.slice(from, to).map((token) => token.raw).join("");
|
|
3899
|
+
}
|
|
3900
|
+
function isExpectedNested(splice, tokens, item) {
|
|
3901
|
+
if (splice.kind === "condition") {
|
|
3902
|
+
return item.kind === "at-rule" && item.atKeyword === splice.atName;
|
|
3903
|
+
}
|
|
3904
|
+
if (item.kind !== "rule" || item.blockStart === void 0) return false;
|
|
3905
|
+
return textOf(tokens, item.start, item.blockStart - 1).trim() === anchorSelectorList(splice.key);
|
|
3906
|
+
}
|
|
3907
|
+
function readRuleThenSentinel(css) {
|
|
3908
|
+
const tokens = tokenize(css);
|
|
3909
|
+
const closerFor = matchBrackets(tokens);
|
|
3910
|
+
const [rule, sentinel, ...rest] = itemsIn(tokens, closerFor, 0, tokens.length);
|
|
3911
|
+
if (rule === void 0 || sentinel === void 0 || rest.length > 0) return void 0;
|
|
3912
|
+
if (rule.blockStart === void 0 || closerFor[rule.blockStart - 1] !== rule.blockEnd) {
|
|
3913
|
+
return void 0;
|
|
3914
|
+
}
|
|
3915
|
+
const isSentinelWhereAppended = textOf(tokens, 0, sentinel.start).length === css.length - SENTINEL.length;
|
|
3916
|
+
const isSentinelText = textOf(tokens, sentinel.start, sentinel.end) === SENTINEL;
|
|
3917
|
+
const isClosedBeforeIt = isOnlyInert(tokens, rule.end, sentinel.start);
|
|
3918
|
+
return isSentinelWhereAppended && isSentinelText && isClosedBeforeIt ? { closerFor, rule, tokens } : void 0;
|
|
3919
|
+
}
|
|
3920
|
+
function isInsideRule(splice) {
|
|
3921
|
+
const { atoms: atoms2, nested } = atomFor(splice);
|
|
3922
|
+
let css;
|
|
3923
|
+
try {
|
|
3924
|
+
css = expandText(`.p { @nave ${ATOM}; }
|
|
3925
|
+
${SENTINEL}`, {
|
|
3926
|
+
extend: atoms2,
|
|
3927
|
+
onUnknown: "ignore"
|
|
3928
|
+
}).css;
|
|
3929
|
+
} catch {
|
|
3930
|
+
return true;
|
|
3931
|
+
}
|
|
3932
|
+
const read = readRuleThenSentinel(css);
|
|
3933
|
+
if (read === void 0) return false;
|
|
3934
|
+
const { closerFor, rule, tokens } = read;
|
|
3935
|
+
const inner = itemsIn(tokens, closerFor, rule.blockStart, rule.blockEnd);
|
|
3936
|
+
const nestedItems = inner.filter((item) => item.kind === "rule" || item.kind === "at-rule");
|
|
3937
|
+
if (nestedItems.length !== nested) return false;
|
|
3938
|
+
return splice.kind === "declarations" || isExpectedNested(splice, tokens, nestedItems[0]);
|
|
3939
|
+
}
|
|
3940
|
+
|
|
3941
|
+
// src/validate-extend-walk.ts
|
|
3942
|
+
function refuse(describedAs, clause) {
|
|
3943
|
+
throw new Error(
|
|
3944
|
+
`navePlugin({ extend }): ${describedAs} ${clause} extend is trusted, consumer-authored code, not sanitised input \u2014 fix the atom definition.`
|
|
3945
|
+
);
|
|
3946
|
+
}
|
|
3947
|
+
var ESCAPED_LESS_THAN = String.raw`\3c`;
|
|
3948
|
+
function fail(describedAs, reason, value, splice) {
|
|
3949
|
+
if (reason === "rewritten") {
|
|
3950
|
+
refuse(
|
|
3951
|
+
describedAs,
|
|
3952
|
+
`parses, but would not be written back exactly as given: ${JSON.stringify(value)}. A "<" before "style", "/style" or "!--" is written back escaped: write the "<" as ${ESCAPED_LESS_THAN} with a space after it (${ESCAPED_LESS_THAN} /style), or as %3C inside a URL. Whitespace at either end of it is not written back as given: remove it.`
|
|
3953
|
+
);
|
|
3954
|
+
}
|
|
3955
|
+
const clause = "does not parse as a single CSS declaration, selector or condition, ";
|
|
3956
|
+
if (isInsideRule(splice)) {
|
|
3957
|
+
refuse(
|
|
3958
|
+
describedAs,
|
|
3959
|
+
`${clause}though it would stay inside the rule it is spliced into: ${JSON.stringify(value)}. Write exactly one, with nothing else in it: no ";" or second declaration, no comment, and no trailing backslash.`
|
|
3960
|
+
);
|
|
3961
|
+
}
|
|
3962
|
+
refuse(
|
|
3963
|
+
describedAs,
|
|
3964
|
+
`${clause}and would break out of the rule it is spliced into: ${JSON.stringify(value)}.`
|
|
3965
|
+
);
|
|
3966
|
+
}
|
|
3967
|
+
function kindOf(value) {
|
|
3968
|
+
if (Array.isArray(value)) return "an array";
|
|
3969
|
+
const boxed = boxedPrimitiveKind(value);
|
|
3970
|
+
return boxed === void 0 ? `a ${typeof value}` : `a ${boxed} object`;
|
|
3971
|
+
}
|
|
3972
|
+
function quoted2(value) {
|
|
3973
|
+
if (typeof value === "function" || typeof value === "symbol") return void 0;
|
|
3974
|
+
if (typeof value === "bigint") return `${value}n`;
|
|
3975
|
+
if (typeof value === "number") return String(value);
|
|
3976
|
+
try {
|
|
3977
|
+
return JSON.stringify(value);
|
|
3978
|
+
} catch {
|
|
3979
|
+
return void 0;
|
|
3980
|
+
}
|
|
3981
|
+
}
|
|
3982
|
+
function printable(value) {
|
|
3983
|
+
const isBoxed = boxedPrimitiveKind(value) !== void 0;
|
|
3984
|
+
return quoted2(isBoxed ? unboxedPrimitive(value) : value);
|
|
3985
|
+
}
|
|
3986
|
+
function failShape(describedAs, value, isAtom) {
|
|
3987
|
+
const printed = printable(value);
|
|
3988
|
+
const shown = printed === void 0 ? "" : `: ${printed}`;
|
|
3989
|
+
const advice = isAtom ? "Write an atom as { declarations: { ... } }." : "Write it as a plain object ({ ... }).";
|
|
3990
|
+
refuse(describedAs, `is ${kindOf(value)}, not a plain object${shown}. ${advice}`);
|
|
3991
|
+
}
|
|
3992
|
+
function assertShape(value, describedAs) {
|
|
3993
|
+
if (!value || isPlainObject(value)) return;
|
|
3994
|
+
failShape(describedAs, value, false);
|
|
3995
|
+
}
|
|
3996
|
+
function assertDeclarationsSafe(declarations, where, p) {
|
|
3997
|
+
assertShape(declarations, `${where}'s declarations`);
|
|
3998
|
+
if (!isPlainObject(declarations)) return;
|
|
3999
|
+
for (const [prop, value] of Object.entries(declarations)) {
|
|
4000
|
+
const propRefusal = p.propRefusal(prop);
|
|
4001
|
+
if (propRefusal) {
|
|
4002
|
+
fail(`${where}'s declaration property "${prop}"`, propRefusal, prop, {
|
|
4003
|
+
declarations: { [prop]: "0" },
|
|
4004
|
+
kind: "declarations"
|
|
4005
|
+
});
|
|
4006
|
+
}
|
|
4007
|
+
if (typeof value !== "string") continue;
|
|
4008
|
+
const valueRefusal = p.declarationRefusal(prop, value);
|
|
4009
|
+
if (valueRefusal) {
|
|
4010
|
+
fail(`${where}'s declaration value for "${prop}"`, valueRefusal, value, {
|
|
4011
|
+
declarations: { [prop]: value },
|
|
4012
|
+
kind: "declarations"
|
|
4013
|
+
});
|
|
4014
|
+
}
|
|
4015
|
+
}
|
|
4016
|
+
}
|
|
4017
|
+
function assertPseudosSafe(pseudos, where, p) {
|
|
4018
|
+
assertShape(pseudos, `${where}'s pseudos`);
|
|
4019
|
+
if (!isPlainObject(pseudos)) return;
|
|
4020
|
+
for (const [pseudo, declarations] of Object.entries(pseudos)) {
|
|
4021
|
+
const refusal = p.selectorRefusal(pseudo);
|
|
4022
|
+
if (refusal) {
|
|
4023
|
+
fail(`${where}'s pseudo "${pseudo}"`, refusal, pseudo, { key: pseudo, kind: "pseudo" });
|
|
4024
|
+
}
|
|
4025
|
+
assertDeclarationsSafe(declarations, `${where}'s pseudo "${pseudo}"`, p);
|
|
4026
|
+
}
|
|
4027
|
+
}
|
|
4028
|
+
function assertAtBlocksSafe(blocks, atName, where, p) {
|
|
4029
|
+
assertShape(blocks, `${where}'s ${atName} map`);
|
|
4030
|
+
if (!isPlainObject(blocks)) return;
|
|
4031
|
+
for (const [condition, block] of Object.entries(blocks)) {
|
|
4032
|
+
const refusal = p.conditionRefusal(atName, condition);
|
|
4033
|
+
if (refusal) {
|
|
4034
|
+
fail(`${where}'s ${atName} condition "${condition}"`, refusal, condition, {
|
|
4035
|
+
atName,
|
|
4036
|
+
condition,
|
|
4037
|
+
kind: "condition"
|
|
4038
|
+
});
|
|
4039
|
+
}
|
|
4040
|
+
const blockWhere2 = `${where}'s ${atName} "${condition}"`;
|
|
4041
|
+
assertShape(block, `${blockWhere2} block`);
|
|
4042
|
+
if (!isPlainObject(block)) continue;
|
|
4043
|
+
assertDeclarationsSafe(block.declarations, blockWhere2, p);
|
|
4044
|
+
assertPseudosSafe(block.pseudos, blockWhere2, p);
|
|
4045
|
+
}
|
|
4046
|
+
}
|
|
4047
|
+
function walkExtendAtoms(extend, predicates) {
|
|
4048
|
+
for (const [name, atom] of Object.entries(extend)) {
|
|
4049
|
+
if (!atom) continue;
|
|
4050
|
+
const where = `atom "${name}"`;
|
|
4051
|
+
if (!isPlainObject(atom)) failShape(where, atom, true);
|
|
4052
|
+
assertDeclarationsSafe(atom.declarations, where, predicates);
|
|
4053
|
+
assertPseudosSafe(atom.pseudos, where, predicates);
|
|
4054
|
+
assertAtBlocksSafe(atom.media, "media", where, predicates);
|
|
4055
|
+
assertAtBlocksSafe(atom.container, "container", where, predicates);
|
|
4056
|
+
}
|
|
4057
|
+
}
|
|
4058
|
+
|
|
4059
|
+
export { DirectiveFailure, WORKAROUND_GROUP_AT_RULE_NAMES, anchorSelectorList, expandText, foldLocated, hasBrokenString, hasEscapedCommentOpener, hasEscapedWhitespace, hasHtmlBreakout, hasPaddedComment, hasStrayCurlyCloser, hasTopLevelColon, hasTopLevelComment, hasUnstrippedLeadingSpace, hasUnstrippedTrailingSpace, hasUrl, isInert3 as isInert, isOnlyInert, lastNonWhitespace, plan, planRule, snapshotExtendMap, walkExtendAtoms };
|