@navecss/core 0.3.0 → 0.4.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/README.md +21 -4
- package/dist/atom-names-2OreuBx9.d.ts +27 -0
- package/dist/atoms.d.ts +3 -13
- package/dist/atoms.js +2 -1
- package/dist/bin.js +6 -4
- package/dist/{chunk-IZQLFUQU.js → chunk-2A7IUZBH.js} +2 -1
- package/dist/{chunk-LIUB4EES.js → chunk-CUL5PLPI.js} +1 -5
- package/dist/chunk-E5F6YF7A.js +2428 -0
- package/dist/chunk-GZL2VW7C.js +57 -0
- package/dist/{chunk-S7DZUVV3.js → chunk-LADFXRWQ.js} +3 -300
- package/dist/{chunk-R6JJZGXC.js → chunk-LQSGQ2OA.js} +1 -1
- package/dist/chunk-SYNQJNVB.js +302 -0
- package/dist/collect.d.ts +279 -0
- package/dist/collect.js +4 -0
- package/dist/cx.d.ts +1 -1
- package/dist/cx.js +14 -1
- package/dist/lightningcss.d.ts +1 -0
- package/dist/lightningcss.js +6 -4
- package/dist/postcss.d.ts +1 -0
- package/dist/postcss.js +4 -2
- package/dist/standalone.css +2 -0
- package/dist/vite-options-D1-hGA9L.d.ts +86 -0
- package/dist/vite.d.ts +5 -67
- package/dist/vite.js +298 -2192
- package/package.json +6 -2
- package/skills/navecss/SKILL.md +2 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// src/atom-names.ts
|
|
2
|
+
var atomNames = [
|
|
3
|
+
"flex",
|
|
4
|
+
"inlineFlex",
|
|
5
|
+
"grid",
|
|
6
|
+
"block",
|
|
7
|
+
"inlineBlock",
|
|
8
|
+
"hidden",
|
|
9
|
+
"flexCol",
|
|
10
|
+
"flexWrap",
|
|
11
|
+
"itemsCenter",
|
|
12
|
+
"itemsStart",
|
|
13
|
+
"itemsEnd",
|
|
14
|
+
"justifyCenter",
|
|
15
|
+
"justifyBetween",
|
|
16
|
+
"justifyEnd",
|
|
17
|
+
"flexGrow",
|
|
18
|
+
"flexShrink0",
|
|
19
|
+
"gap",
|
|
20
|
+
"relative",
|
|
21
|
+
"absolute",
|
|
22
|
+
"insetFull",
|
|
23
|
+
"wFull",
|
|
24
|
+
"hFull",
|
|
25
|
+
"minW0",
|
|
26
|
+
"truncate",
|
|
27
|
+
"srOnly",
|
|
28
|
+
"srOnlyFocusable",
|
|
29
|
+
"noWrap",
|
|
30
|
+
"breakWord",
|
|
31
|
+
"textLeft",
|
|
32
|
+
"textCenter",
|
|
33
|
+
"textRight",
|
|
34
|
+
"interactive",
|
|
35
|
+
"focusRing",
|
|
36
|
+
"disabledState",
|
|
37
|
+
"rounded",
|
|
38
|
+
"roundedCard",
|
|
39
|
+
"roundedFull",
|
|
40
|
+
"border",
|
|
41
|
+
"overflowHidden",
|
|
42
|
+
"overflowAuto",
|
|
43
|
+
"transition",
|
|
44
|
+
"container",
|
|
45
|
+
"hidePhoneOnly",
|
|
46
|
+
"hideTabletPortraitUp",
|
|
47
|
+
"hideTabletLandscapeUp",
|
|
48
|
+
"hideDesktopUp",
|
|
49
|
+
"stackPhoneOnly",
|
|
50
|
+
"wFullPhoneOnly"
|
|
51
|
+
];
|
|
52
|
+
var toClassName = (name) => `nave-${name.replaceAll(/([A-Z])/g, "-$1").toLowerCase()}`;
|
|
53
|
+
var atomClassMap = Object.fromEntries(
|
|
54
|
+
atomNames.map((name) => [name, toClassName(name)])
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
export { atomClassMap, toClassName };
|
|
@@ -1,186 +1,6 @@
|
|
|
1
1
|
import { reportDiagnostics, tokenize, matchBrackets, createPositionFinder, readItem, isNaveAtKeyword, atKeywordName, OPENERS } from './chunk-NFS2REPQ.js';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
// src/directive/source-map.ts
|
|
5
|
-
var BASE64_DIGITS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
6
|
-
var NEWLINE_CHARS = /* @__PURE__ */ new Set(["\n", "\r", "\f"]);
|
|
7
|
-
function encodeVLQ(n) {
|
|
8
|
-
let value = n < 0 ? (-n << 1) + 1 : n << 1;
|
|
9
|
-
let result = "";
|
|
10
|
-
do {
|
|
11
|
-
let digit = value & 31;
|
|
12
|
-
value >>>= 5;
|
|
13
|
-
if (value > 0) digit |= 32;
|
|
14
|
-
result += BASE64_DIGITS[digit];
|
|
15
|
-
} while (value > 0);
|
|
16
|
-
return result;
|
|
17
|
-
}
|
|
18
|
-
var BASE64_VALUE = new Map([...BASE64_DIGITS].map((c, i) => [c, i]));
|
|
19
|
-
function decodeVLQSegment(mappings, start) {
|
|
20
|
-
let value = 0;
|
|
21
|
-
let shift = 0;
|
|
22
|
-
let i = start;
|
|
23
|
-
for (; ; ) {
|
|
24
|
-
const digit = BASE64_VALUE.get(mappings[i]);
|
|
25
|
-
i++;
|
|
26
|
-
value += (digit & 31) << shift;
|
|
27
|
-
if ((digit & 32) === 0) break;
|
|
28
|
-
shift += 5;
|
|
29
|
-
}
|
|
30
|
-
const isNegative = (value & 1) === 1;
|
|
31
|
-
const magnitude = value >>> 1;
|
|
32
|
-
return { value: isNegative ? -magnitude : magnitude, next: i };
|
|
33
|
-
}
|
|
34
|
-
var MappingsBuilder = class {
|
|
35
|
-
hasSegmentOnLine = false;
|
|
36
|
-
lines = [[]];
|
|
37
|
-
outputColumn = 0;
|
|
38
|
-
outputLine = 0;
|
|
39
|
-
// A lone trailing `\r`, possibly half of a CRLF pair split across two
|
|
40
|
-
// `advance()` calls by a removed directive: consumed by the next call's
|
|
41
|
-
// leading `\n`, if any, instead of double-counted.
|
|
42
|
-
pendingCR = false;
|
|
43
|
-
prevGeneratedColumn = 0;
|
|
44
|
-
prevSourceColumn = 0;
|
|
45
|
-
prevSourceIndex = 0;
|
|
46
|
-
prevSourceLine = 0;
|
|
47
|
-
/**
|
|
48
|
-
* A plain indexed loop, not `for...of` (which iterates by code point, so
|
|
49
|
-
* a surrogate pair would advance the column by one instead of two — every
|
|
50
|
-
* position here is in UTF-16 code units). A line break is CR, FF, LF or a
|
|
51
|
-
* CRLF pair, CSS Syntax 3's own "newline" (§4.2).
|
|
52
|
-
*/
|
|
53
|
-
advance(text) {
|
|
54
|
-
let i = this.consumePendingCR(text);
|
|
55
|
-
while (i < text.length) {
|
|
56
|
-
const c = text[i];
|
|
57
|
-
if (c !== void 0 && NEWLINE_CHARS.has(c)) {
|
|
58
|
-
i = this.advancePastNewline(text, i, c);
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
this.outputColumn++;
|
|
62
|
-
i++;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* `i` past the line break `c` (at `i`): past the whole pair for a `\r`
|
|
67
|
-
* immediately followed by `\n`, and `pendingCR` set instead when `\r` is
|
|
68
|
-
* the last character `text` has to offer.
|
|
69
|
-
*/
|
|
70
|
-
advancePastNewline(text, i, c) {
|
|
71
|
-
let next = i + 1;
|
|
72
|
-
if (c === "\r" && text[next] === "\n") {
|
|
73
|
-
next++;
|
|
74
|
-
} else if (c === "\r" && next === text.length) {
|
|
75
|
-
this.pendingCR = true;
|
|
76
|
-
}
|
|
77
|
-
this.outputLine++;
|
|
78
|
-
this.outputColumn = 0;
|
|
79
|
-
this.lines.push([]);
|
|
80
|
-
this.prevGeneratedColumn = 0;
|
|
81
|
-
this.hasSegmentOnLine = false;
|
|
82
|
-
return next;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* How far into `text` `advance` should start: `1` for a lone `\n` that is
|
|
86
|
-
* really the other half of a CRLF pair split across two calls; `0`
|
|
87
|
-
* otherwise.
|
|
88
|
-
*/
|
|
89
|
-
consumePendingCR(text) {
|
|
90
|
-
if (text.length === 0) return 0;
|
|
91
|
-
const skip = this.pendingCR && text.startsWith("\n") ? 1 : 0;
|
|
92
|
-
this.pendingCR = false;
|
|
93
|
-
return skip;
|
|
94
|
-
}
|
|
95
|
-
mark(position) {
|
|
96
|
-
const sourceIndex = position.sourceIndex ?? 0;
|
|
97
|
-
const sourceLine = position.line - 1;
|
|
98
|
-
const generatedColumnDelta = this.hasSegmentOnLine ? this.outputColumn - this.prevGeneratedColumn : this.outputColumn;
|
|
99
|
-
const sourceIndexDelta = sourceIndex - this.prevSourceIndex;
|
|
100
|
-
const sourceLineDelta = sourceLine - this.prevSourceLine;
|
|
101
|
-
const sourceColumnDelta = position.column - this.prevSourceColumn;
|
|
102
|
-
this.lines[this.outputLine].push(
|
|
103
|
-
encodeVLQ(generatedColumnDelta) + encodeVLQ(sourceIndexDelta) + encodeVLQ(sourceLineDelta) + encodeVLQ(sourceColumnDelta)
|
|
104
|
-
);
|
|
105
|
-
this.prevGeneratedColumn = this.outputColumn;
|
|
106
|
-
this.prevSourceIndex = sourceIndex;
|
|
107
|
-
this.prevSourceLine = sourceLine;
|
|
108
|
-
this.prevSourceColumn = position.column;
|
|
109
|
-
this.hasSegmentOnLine = true;
|
|
110
|
-
}
|
|
111
|
-
toMappings() {
|
|
112
|
-
return this.lines.map((segments) => segments.join(",")).join(";");
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
function findCandidate(segments, position) {
|
|
116
|
-
const generatedLine = position.line - 1;
|
|
117
|
-
let low = 0;
|
|
118
|
-
let high = segments.length - 1;
|
|
119
|
-
let candidate;
|
|
120
|
-
while (low <= high) {
|
|
121
|
-
const mid = low + high >> 1;
|
|
122
|
-
const segment = segments[mid];
|
|
123
|
-
const isAtOrBefore = segment.generatedLine < generatedLine || segment.generatedLine === generatedLine && segment.generatedColumn <= position.column;
|
|
124
|
-
if (isAtOrBefore) {
|
|
125
|
-
candidate = segment;
|
|
126
|
-
low = mid + 1;
|
|
127
|
-
} else {
|
|
128
|
-
high = mid - 1;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return candidate?.generatedLine === generatedLine ? candidate : void 0;
|
|
132
|
-
}
|
|
133
|
-
function decodeIncomingMap(map) {
|
|
134
|
-
const sources = map.sources;
|
|
135
|
-
const segments = decodeSegments(map.mappings);
|
|
136
|
-
return {
|
|
137
|
-
sources,
|
|
138
|
-
sourceRoot: map.sourceRoot,
|
|
139
|
-
sourcesContent: map.sourcesContent,
|
|
140
|
-
originalPositionFor(position) {
|
|
141
|
-
const candidate = findCandidate(segments, position);
|
|
142
|
-
if (!candidate) return;
|
|
143
|
-
return {
|
|
144
|
-
source: sources[candidate.sourceIndex],
|
|
145
|
-
sourceIndex: candidate.sourceIndex,
|
|
146
|
-
line: candidate.sourceLine + 1,
|
|
147
|
-
column: candidate.sourceColumn
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
function decodeOneSegment(state, raw, generatedLine) {
|
|
153
|
-
const col = decodeVLQSegment(raw, 0);
|
|
154
|
-
state.generatedColumn += col.value;
|
|
155
|
-
if (col.next >= raw.length) return void 0;
|
|
156
|
-
const srcIdx = decodeVLQSegment(raw, col.next);
|
|
157
|
-
state.sourceIndex += srcIdx.value;
|
|
158
|
-
const srcLine = decodeVLQSegment(raw, srcIdx.next);
|
|
159
|
-
state.sourceLine += srcLine.value;
|
|
160
|
-
const srcCol = decodeVLQSegment(raw, srcLine.next);
|
|
161
|
-
state.sourceColumn += srcCol.value;
|
|
162
|
-
return {
|
|
163
|
-
generatedLine,
|
|
164
|
-
generatedColumn: state.generatedColumn,
|
|
165
|
-
sourceIndex: state.sourceIndex,
|
|
166
|
-
sourceLine: state.sourceLine,
|
|
167
|
-
sourceColumn: state.sourceColumn
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
function decodeSegments(mappings) {
|
|
171
|
-
const segments = [];
|
|
172
|
-
const state = { generatedColumn: 0, sourceIndex: 0, sourceLine: 0, sourceColumn: 0 };
|
|
173
|
-
const lines = mappings.split(";");
|
|
174
|
-
for (const [generatedLine, line] of lines.entries()) {
|
|
175
|
-
state.generatedColumn = 0;
|
|
176
|
-
if (line === "") continue;
|
|
177
|
-
for (const raw of line.split(",")) {
|
|
178
|
-
const segment = decodeOneSegment(state, raw, generatedLine);
|
|
179
|
-
if (segment) segments.push(segment);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return segments;
|
|
183
|
-
}
|
|
2
|
+
import { decodeIncomingMap, MappingsBuilder } from './chunk-SYNQJNVB.js';
|
|
3
|
+
import { atoms } from './chunk-CUL5PLPI.js';
|
|
184
4
|
|
|
185
5
|
// src/directive/expand-text-output.ts
|
|
186
6
|
function toOriginal(position, incoming) {
|
|
@@ -956,123 +776,6 @@ function snapshotExtendMap(map) {
|
|
|
956
776
|
return out;
|
|
957
777
|
}
|
|
958
778
|
|
|
959
|
-
// src/directive/diagnostics-format.ts
|
|
960
|
-
function vocabulary(extend) {
|
|
961
|
-
const extendKeys = new Set(Object.keys(extend));
|
|
962
|
-
const names = [];
|
|
963
|
-
for (const [name, definition] of Object.entries(atoms)) {
|
|
964
|
-
if (definition && !extendKeys.has(name)) names.push(name);
|
|
965
|
-
}
|
|
966
|
-
for (const [name, definition] of Object.entries(extend)) {
|
|
967
|
-
if (definition) names.push(name);
|
|
968
|
-
}
|
|
969
|
-
return names;
|
|
970
|
-
}
|
|
971
|
-
function distance(a, b) {
|
|
972
|
-
const d = [];
|
|
973
|
-
for (let i = 0; i <= a.length; i++) d.push([i]);
|
|
974
|
-
for (let j = 0; j <= b.length; j++) d[0][j] = j;
|
|
975
|
-
for (let i = 1; i <= a.length; i++) {
|
|
976
|
-
for (let j = 1; j <= b.length; j++) {
|
|
977
|
-
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
978
|
-
let best = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
|
|
979
|
-
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
|
|
980
|
-
best = Math.min(best, d[i - 2][j - 2] + 1);
|
|
981
|
-
}
|
|
982
|
-
d[i][j] = best;
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
return d[a.length][b.length];
|
|
986
|
-
}
|
|
987
|
-
function normalize(name) {
|
|
988
|
-
const lower = name.toLowerCase();
|
|
989
|
-
const withoutPrefix = lower.startsWith("nave-") ? lower.slice(5) : lower;
|
|
990
|
-
return withoutPrefix.replaceAll("-", "");
|
|
991
|
-
}
|
|
992
|
-
function groupByDistance(normalizedTyped, names) {
|
|
993
|
-
let minDistance = Infinity;
|
|
994
|
-
const byDistance = /* @__PURE__ */ new Map();
|
|
995
|
-
for (const name of names) {
|
|
996
|
-
const d = distance(normalizedTyped, normalize(name));
|
|
997
|
-
if (!byDistance.has(d)) byDistance.set(d, []);
|
|
998
|
-
byDistance.get(d).push(name);
|
|
999
|
-
if (d < minDistance) minDistance = d;
|
|
1000
|
-
}
|
|
1001
|
-
return { byDistance, minDistance };
|
|
1002
|
-
}
|
|
1003
|
-
function hasCamelCaseNote(typed, candidates, minDistance, extend) {
|
|
1004
|
-
if (minDistance !== 0 || candidates.length !== 1) return false;
|
|
1005
|
-
if (!typed.includes("-")) return false;
|
|
1006
|
-
const candidate = candidates[0];
|
|
1007
|
-
const shadow = extend[candidate];
|
|
1008
|
-
if (shadow) return false;
|
|
1009
|
-
return Object.hasOwn(atomClassMap, candidate);
|
|
1010
|
-
}
|
|
1011
|
-
function findHint(typed, extend) {
|
|
1012
|
-
const normalizedTyped = normalize(typed);
|
|
1013
|
-
const { byDistance, minDistance } = groupByDistance(normalizedTyped, vocabulary(extend));
|
|
1014
|
-
if (minDistance > 2 || minDistance >= normalizedTyped.length / 2) return void 0;
|
|
1015
|
-
const candidates = byDistance.get(minDistance) ?? [];
|
|
1016
|
-
if (candidates.length === 0) return void 0;
|
|
1017
|
-
return { candidates, camelCaseNote: hasCamelCaseNote(typed, candidates, minDistance, extend) };
|
|
1018
|
-
}
|
|
1019
|
-
function quoteList(items) {
|
|
1020
|
-
if (items.length === 1) return `"${items[0]}"`;
|
|
1021
|
-
return `${items.slice(0, -1).map((i) => `"${i}"`).join(", ")} or "${items.at(-1)}"`;
|
|
1022
|
-
}
|
|
1023
|
-
function formatUnknownAtom(name, extend) {
|
|
1024
|
-
const first = `@nave: unknown atom "${name}".`;
|
|
1025
|
-
const hint = findHint(name, extend);
|
|
1026
|
-
if (hint) {
|
|
1027
|
-
const camelCase = hint.camelCaseNote ? ` Atom names are camelCase; "${atomClassMap[hint.candidates[0]]}" is its class.` : "";
|
|
1028
|
-
return `${first} Did you mean ${quoteList(hint.candidates)}?${camelCase}`;
|
|
1029
|
-
}
|
|
1030
|
-
const available = vocabulary(extend).join(", ");
|
|
1031
|
-
return `${first} If it is an atom of your own, pass it in the extend option.
|
|
1032
|
-
Available: ${available}`;
|
|
1033
|
-
}
|
|
1034
|
-
var ANSWERED_BY_STANDALONE = /* @__PURE__ */ new Set([
|
|
1035
|
-
"@navecss/core",
|
|
1036
|
-
"@navecss/core/atomic",
|
|
1037
|
-
"@navecss/core/layers",
|
|
1038
|
-
"@navecss/core/reset",
|
|
1039
|
-
"@navecss/core/standalone",
|
|
1040
|
-
"@navecss/tokens/css"
|
|
1041
|
-
]);
|
|
1042
|
-
var STANDALONE_PATH = "node_modules/@navecss/core/dist/standalone.css";
|
|
1043
|
-
var STANDALONE_CDN_URL = "https://cdn.jsdelivr.net/npm/@navecss/core@<version>/dist/standalone.css";
|
|
1044
|
-
var NO_TOKENS_PATH = "node_modules/@navecss/core/dist/no-tokens.css";
|
|
1045
|
-
var NO_TOKENS_CDN_URL = "https://cdn.jsdelivr.net/npm/@navecss/core@<version>/dist/no-tokens.css";
|
|
1046
|
-
var BAD_PARENT_WORKAROUND = ". A directive here can be written `& { @nave ...; }` inside the group rule instead.";
|
|
1047
|
-
function formatBadParent(diagnostic) {
|
|
1048
|
-
const workaround = diagnostic.detail === "nested-group" ? BAD_PARENT_WORKAROUND : "";
|
|
1049
|
-
return `@nave must be the direct child of a CSS rule selector block${workaround}`;
|
|
1050
|
-
}
|
|
1051
|
-
var FIXED_TEXTS = {
|
|
1052
|
-
"bad-token": (d) => `@nave: unexpected "${d.text ?? ""}"; a directive takes only atom names (separate atom names with spaces)`,
|
|
1053
|
-
"bare-import": (d) => {
|
|
1054
|
-
const specifier = d.text ?? "";
|
|
1055
|
-
const quoted2 = JSON.stringify(specifier);
|
|
1056
|
-
if (ANSWERED_BY_STANDALONE.has(specifier)) {
|
|
1057
|
-
return `@import ${quoted2} names a package, so a browser cannot load it. Link Nave's self-contained stylesheet from the page instead, ahead of your own stylesheets: ${STANDALONE_PATH}, or ${STANDALONE_CDN_URL} with <version> replaced by the version you installed.`;
|
|
1058
|
-
}
|
|
1059
|
-
if (specifier === "@navecss/core/no-tokens") {
|
|
1060
|
-
return `@import ${quoted2} names a package, so a browser cannot load it. Link that entry's own file from the page instead, ahead of your own stylesheets: ${NO_TOKENS_PATH}, or ${NO_TOKENS_CDN_URL} with <version> replaced by the version you installed. Not the self-contained stylesheet: it holds Nave's token layer, which this entry leaves out.`;
|
|
1061
|
-
}
|
|
1062
|
-
return `@import ${quoted2} names no file relative to the output, so a browser cannot load it. Point it at a file the page can reach, by a path that works from the output or by a URL, or bundle the stylesheet.`;
|
|
1063
|
-
},
|
|
1064
|
-
"has-block": () => "@nave: a directive with a {} block is not supported",
|
|
1065
|
-
"in-keyframes": () => "@nave cannot be used inside @keyframes",
|
|
1066
|
-
"missing-declarations": (d) => `@nave: atom "${d.name ?? ""}" is registered without a declarations object`,
|
|
1067
|
-
"no-atom": () => "@nave: directive names no atom"
|
|
1068
|
-
};
|
|
1069
|
-
function formatDiagnostic(diagnostic, options = {}) {
|
|
1070
|
-
if (diagnostic.code === "unknown-atom")
|
|
1071
|
-
return formatUnknownAtom(diagnostic.name, options.extend ?? {});
|
|
1072
|
-
if (diagnostic.code === "bad-parent") return formatBadParent(diagnostic);
|
|
1073
|
-
return FIXED_TEXTS[diagnostic.code](diagnostic);
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
779
|
// src/directive/fold.ts
|
|
1077
780
|
function splitAvailable(text) {
|
|
1078
781
|
const lines = text.split("\n");
|
|
@@ -1383,4 +1086,4 @@ function walkExtendAtoms(extend, predicates) {
|
|
|
1383
1086
|
}
|
|
1384
1087
|
}
|
|
1385
1088
|
|
|
1386
|
-
export { WORKAROUND_GROUP_AT_RULE_NAMES, anchorSelectorList,
|
|
1089
|
+
export { WORKAROUND_GROUP_AT_RULE_NAMES, anchorSelectorList, expandText, foldLocated, hasBrokenString, hasEscapedCommentOpener, hasEscapedWhitespace, hasHtmlBreakout, hasPaddedComment, hasStrayCurlyCloser, hasTopLevelColon, hasTopLevelComment, hasUnstrippedLeadingSpace, hasUnstrippedTrailingSpace, hasUrl, isInert, isOnlyInert, lastNonWhitespace, plan, snapshotExtendMap, walkExtendAtoms };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { walkExtendAtoms, hasEscapedCommentOpener, isOnlyInert, hasTopLevelComment, hasUnstrippedTrailingSpace, hasUnstrippedLeadingSpace, lastNonWhitespace, isInert, hasPaddedComment, hasBrokenString, hasUrl, hasStrayCurlyCloser, anchorSelectorList, hasEscapedWhitespace, hasHtmlBreakout, hasTopLevelColon } from './chunk-
|
|
1
|
+
import { walkExtendAtoms, hasEscapedCommentOpener, isOnlyInert, hasTopLevelComment, hasUnstrippedTrailingSpace, hasUnstrippedLeadingSpace, lastNonWhitespace, isInert, hasPaddedComment, hasBrokenString, hasUrl, hasStrayCurlyCloser, anchorSelectorList, hasEscapedWhitespace, hasHtmlBreakout, hasTopLevelColon } from './chunk-LADFXRWQ.js';
|
|
2
2
|
import { tokenize, matchBrackets, readItem } from './chunk-NFS2REPQ.js';
|
|
3
3
|
|
|
4
4
|
// src/validate-extend-host-free.ts
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { atoms } from './chunk-CUL5PLPI.js';
|
|
2
|
+
import { atomClassMap } from './chunk-GZL2VW7C.js';
|
|
3
|
+
|
|
4
|
+
// src/directive/diagnostics-format.ts
|
|
5
|
+
function vocabulary(extend) {
|
|
6
|
+
const extendKeys = new Set(Object.keys(extend));
|
|
7
|
+
const names = [];
|
|
8
|
+
for (const [name, definition] of Object.entries(atoms)) {
|
|
9
|
+
if (definition && !extendKeys.has(name)) names.push(name);
|
|
10
|
+
}
|
|
11
|
+
for (const [name, definition] of Object.entries(extend)) {
|
|
12
|
+
if (definition) names.push(name);
|
|
13
|
+
}
|
|
14
|
+
return names;
|
|
15
|
+
}
|
|
16
|
+
function distance(a, b) {
|
|
17
|
+
const d = [];
|
|
18
|
+
for (let i = 0; i <= a.length; i++) d.push([i]);
|
|
19
|
+
for (let j = 0; j <= b.length; j++) d[0][j] = j;
|
|
20
|
+
for (let i = 1; i <= a.length; i++) {
|
|
21
|
+
for (let j = 1; j <= b.length; j++) {
|
|
22
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
23
|
+
let best = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
|
|
24
|
+
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
|
|
25
|
+
best = Math.min(best, d[i - 2][j - 2] + 1);
|
|
26
|
+
}
|
|
27
|
+
d[i][j] = best;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return d[a.length][b.length];
|
|
31
|
+
}
|
|
32
|
+
function normalize(name) {
|
|
33
|
+
const lower = name.toLowerCase();
|
|
34
|
+
const withoutPrefix = lower.startsWith("nave-") ? lower.slice(5) : lower;
|
|
35
|
+
return withoutPrefix.replaceAll("-", "");
|
|
36
|
+
}
|
|
37
|
+
function groupByDistance(normalizedTyped, names) {
|
|
38
|
+
let minDistance = Infinity;
|
|
39
|
+
const byDistance = /* @__PURE__ */ new Map();
|
|
40
|
+
for (const name of names) {
|
|
41
|
+
const d = distance(normalizedTyped, normalize(name));
|
|
42
|
+
if (!byDistance.has(d)) byDistance.set(d, []);
|
|
43
|
+
byDistance.get(d).push(name);
|
|
44
|
+
if (d < minDistance) minDistance = d;
|
|
45
|
+
}
|
|
46
|
+
return { byDistance, minDistance };
|
|
47
|
+
}
|
|
48
|
+
function hasCamelCaseNote(typed, candidates, minDistance, extend) {
|
|
49
|
+
if (minDistance !== 0 || candidates.length !== 1) return false;
|
|
50
|
+
if (!typed.includes("-")) return false;
|
|
51
|
+
const candidate = candidates[0];
|
|
52
|
+
const shadow = extend[candidate];
|
|
53
|
+
if (shadow) return false;
|
|
54
|
+
return Object.hasOwn(atomClassMap, candidate);
|
|
55
|
+
}
|
|
56
|
+
function findHint(typed, extend) {
|
|
57
|
+
const normalizedTyped = normalize(typed);
|
|
58
|
+
const { byDistance, minDistance } = groupByDistance(normalizedTyped, vocabulary(extend));
|
|
59
|
+
if (minDistance > 2 || minDistance >= normalizedTyped.length / 2) return void 0;
|
|
60
|
+
const candidates = byDistance.get(minDistance) ?? [];
|
|
61
|
+
if (candidates.length === 0) return void 0;
|
|
62
|
+
return { candidates, camelCaseNote: hasCamelCaseNote(typed, candidates, minDistance, extend) };
|
|
63
|
+
}
|
|
64
|
+
function quoteList(items) {
|
|
65
|
+
if (items.length === 1) return `"${items[0]}"`;
|
|
66
|
+
return `${items.slice(0, -1).map((i) => `"${i}"`).join(", ")} or "${items.at(-1)}"`;
|
|
67
|
+
}
|
|
68
|
+
function formatUnknownAtom(name, extend) {
|
|
69
|
+
const first = `@nave: unknown atom "${name}".`;
|
|
70
|
+
const hint = findHint(name, extend);
|
|
71
|
+
if (hint) {
|
|
72
|
+
const camelCase = hint.camelCaseNote ? ` Atom names are camelCase; "${atomClassMap[hint.candidates[0]]}" is its class.` : "";
|
|
73
|
+
return `${first} Did you mean ${quoteList(hint.candidates)}?${camelCase}`;
|
|
74
|
+
}
|
|
75
|
+
const available = vocabulary(extend).join(", ");
|
|
76
|
+
return `${first} If it is an atom of your own, pass it in the extend option.
|
|
77
|
+
Available: ${available}`;
|
|
78
|
+
}
|
|
79
|
+
var ANSWERED_BY_STANDALONE = /* @__PURE__ */ new Set([
|
|
80
|
+
"@navecss/core",
|
|
81
|
+
"@navecss/core/atomic",
|
|
82
|
+
"@navecss/core/layers",
|
|
83
|
+
"@navecss/core/reset",
|
|
84
|
+
"@navecss/core/standalone",
|
|
85
|
+
"@navecss/tokens/css"
|
|
86
|
+
]);
|
|
87
|
+
var STANDALONE_PATH = "node_modules/@navecss/core/dist/standalone.css";
|
|
88
|
+
var STANDALONE_CDN_URL = "https://cdn.jsdelivr.net/npm/@navecss/core@<version>/dist/standalone.css";
|
|
89
|
+
var NO_TOKENS_PATH = "node_modules/@navecss/core/dist/no-tokens.css";
|
|
90
|
+
var NO_TOKENS_CDN_URL = "https://cdn.jsdelivr.net/npm/@navecss/core@<version>/dist/no-tokens.css";
|
|
91
|
+
var BAD_PARENT_WORKAROUND = ". A directive here can be written `& { @nave ...; }` inside the group rule instead.";
|
|
92
|
+
function formatBadParent(diagnostic) {
|
|
93
|
+
const workaround = diagnostic.detail === "nested-group" ? BAD_PARENT_WORKAROUND : "";
|
|
94
|
+
return `@nave must be the direct child of a CSS rule selector block${workaround}`;
|
|
95
|
+
}
|
|
96
|
+
var FIXED_TEXTS = {
|
|
97
|
+
"bad-token": (d) => `@nave: unexpected "${d.text ?? ""}"; a directive takes only atom names (separate atom names with spaces)`,
|
|
98
|
+
"bare-import": (d) => {
|
|
99
|
+
const specifier = d.text ?? "";
|
|
100
|
+
const quoted = JSON.stringify(specifier);
|
|
101
|
+
if (ANSWERED_BY_STANDALONE.has(specifier)) {
|
|
102
|
+
return `@import ${quoted} names a package, so a browser cannot load it. Link Nave's self-contained stylesheet from the page instead, ahead of your own stylesheets: ${STANDALONE_PATH}, or ${STANDALONE_CDN_URL} with <version> replaced by the version you installed.`;
|
|
103
|
+
}
|
|
104
|
+
if (specifier === "@navecss/core/no-tokens") {
|
|
105
|
+
return `@import ${quoted} names a package, so a browser cannot load it. Link that entry's own file from the page instead, ahead of your own stylesheets: ${NO_TOKENS_PATH}, or ${NO_TOKENS_CDN_URL} with <version> replaced by the version you installed. Not the self-contained stylesheet: it holds Nave's token layer, which this entry leaves out.`;
|
|
106
|
+
}
|
|
107
|
+
return `@import ${quoted} names no file relative to the output, so a browser cannot load it. Point it at a file the page can reach, by a path that works from the output or by a URL, or bundle the stylesheet.`;
|
|
108
|
+
},
|
|
109
|
+
"has-block": () => "@nave: a directive with a {} block is not supported",
|
|
110
|
+
"in-keyframes": () => "@nave cannot be used inside @keyframes",
|
|
111
|
+
"missing-declarations": (d) => `@nave: atom "${d.name ?? ""}" is registered without a declarations object`,
|
|
112
|
+
"no-atom": () => "@nave: directive names no atom"
|
|
113
|
+
};
|
|
114
|
+
function formatDiagnostic(diagnostic, options = {}) {
|
|
115
|
+
if (diagnostic.code === "unknown-atom")
|
|
116
|
+
return formatUnknownAtom(diagnostic.name, options.extend ?? {});
|
|
117
|
+
if (diagnostic.code === "bad-parent") return formatBadParent(diagnostic);
|
|
118
|
+
return FIXED_TEXTS[diagnostic.code](diagnostic);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/directive/source-map.ts
|
|
122
|
+
var BASE64_DIGITS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
123
|
+
var NEWLINE_CHARS = /* @__PURE__ */ new Set(["\n", "\r", "\f"]);
|
|
124
|
+
function encodeVLQ(n) {
|
|
125
|
+
let value = n < 0 ? (-n << 1) + 1 : n << 1;
|
|
126
|
+
let result = "";
|
|
127
|
+
do {
|
|
128
|
+
let digit = value & 31;
|
|
129
|
+
value >>>= 5;
|
|
130
|
+
if (value > 0) digit |= 32;
|
|
131
|
+
result += BASE64_DIGITS[digit];
|
|
132
|
+
} while (value > 0);
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
var BASE64_VALUE = new Map([...BASE64_DIGITS].map((c, i) => [c, i]));
|
|
136
|
+
function decodeVLQSegment(mappings, start) {
|
|
137
|
+
let value = 0;
|
|
138
|
+
let shift = 0;
|
|
139
|
+
let i = start;
|
|
140
|
+
for (; ; ) {
|
|
141
|
+
const digit = BASE64_VALUE.get(mappings[i]);
|
|
142
|
+
i++;
|
|
143
|
+
value += (digit & 31) << shift;
|
|
144
|
+
if ((digit & 32) === 0) break;
|
|
145
|
+
shift += 5;
|
|
146
|
+
}
|
|
147
|
+
const isNegative = (value & 1) === 1;
|
|
148
|
+
const magnitude = value >>> 1;
|
|
149
|
+
return { value: isNegative ? -magnitude : magnitude, next: i };
|
|
150
|
+
}
|
|
151
|
+
var MappingsBuilder = class {
|
|
152
|
+
hasSegmentOnLine = false;
|
|
153
|
+
lines = [[]];
|
|
154
|
+
outputColumn = 0;
|
|
155
|
+
outputLine = 0;
|
|
156
|
+
// A lone trailing `\r`, possibly half of a CRLF pair split across two
|
|
157
|
+
// `advance()` calls by a removed directive: consumed by the next call's
|
|
158
|
+
// leading `\n`, if any, instead of double-counted.
|
|
159
|
+
pendingCR = false;
|
|
160
|
+
prevGeneratedColumn = 0;
|
|
161
|
+
prevSourceColumn = 0;
|
|
162
|
+
prevSourceIndex = 0;
|
|
163
|
+
prevSourceLine = 0;
|
|
164
|
+
/**
|
|
165
|
+
* A plain indexed loop, not `for...of` (which iterates by code point, so
|
|
166
|
+
* a surrogate pair would advance the column by one instead of two — every
|
|
167
|
+
* position here is in UTF-16 code units). A line break is CR, FF, LF or a
|
|
168
|
+
* CRLF pair, CSS Syntax 3's own "newline" (§4.2).
|
|
169
|
+
*/
|
|
170
|
+
advance(text) {
|
|
171
|
+
let i = this.consumePendingCR(text);
|
|
172
|
+
while (i < text.length) {
|
|
173
|
+
const c = text[i];
|
|
174
|
+
if (c !== void 0 && NEWLINE_CHARS.has(c)) {
|
|
175
|
+
i = this.advancePastNewline(text, i, c);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
this.outputColumn++;
|
|
179
|
+
i++;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* `i` past the line break `c` (at `i`): past the whole pair for a `\r`
|
|
184
|
+
* immediately followed by `\n`, and `pendingCR` set instead when `\r` is
|
|
185
|
+
* the last character `text` has to offer.
|
|
186
|
+
*/
|
|
187
|
+
advancePastNewline(text, i, c) {
|
|
188
|
+
let next = i + 1;
|
|
189
|
+
if (c === "\r" && text[next] === "\n") {
|
|
190
|
+
next++;
|
|
191
|
+
} else if (c === "\r" && next === text.length) {
|
|
192
|
+
this.pendingCR = true;
|
|
193
|
+
}
|
|
194
|
+
this.outputLine++;
|
|
195
|
+
this.outputColumn = 0;
|
|
196
|
+
this.lines.push([]);
|
|
197
|
+
this.prevGeneratedColumn = 0;
|
|
198
|
+
this.hasSegmentOnLine = false;
|
|
199
|
+
return next;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* How far into `text` `advance` should start: `1` for a lone `\n` that is
|
|
203
|
+
* really the other half of a CRLF pair split across two calls; `0`
|
|
204
|
+
* otherwise.
|
|
205
|
+
*/
|
|
206
|
+
consumePendingCR(text) {
|
|
207
|
+
if (text.length === 0) return 0;
|
|
208
|
+
const skip = this.pendingCR && text.startsWith("\n") ? 1 : 0;
|
|
209
|
+
this.pendingCR = false;
|
|
210
|
+
return skip;
|
|
211
|
+
}
|
|
212
|
+
mark(position) {
|
|
213
|
+
const sourceIndex = position.sourceIndex ?? 0;
|
|
214
|
+
const sourceLine = position.line - 1;
|
|
215
|
+
const generatedColumnDelta = this.hasSegmentOnLine ? this.outputColumn - this.prevGeneratedColumn : this.outputColumn;
|
|
216
|
+
const sourceIndexDelta = sourceIndex - this.prevSourceIndex;
|
|
217
|
+
const sourceLineDelta = sourceLine - this.prevSourceLine;
|
|
218
|
+
const sourceColumnDelta = position.column - this.prevSourceColumn;
|
|
219
|
+
this.lines[this.outputLine].push(
|
|
220
|
+
encodeVLQ(generatedColumnDelta) + encodeVLQ(sourceIndexDelta) + encodeVLQ(sourceLineDelta) + encodeVLQ(sourceColumnDelta)
|
|
221
|
+
);
|
|
222
|
+
this.prevGeneratedColumn = this.outputColumn;
|
|
223
|
+
this.prevSourceIndex = sourceIndex;
|
|
224
|
+
this.prevSourceLine = sourceLine;
|
|
225
|
+
this.prevSourceColumn = position.column;
|
|
226
|
+
this.hasSegmentOnLine = true;
|
|
227
|
+
}
|
|
228
|
+
toMappings() {
|
|
229
|
+
return this.lines.map((segments) => segments.join(",")).join(";");
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
function findCandidate(segments, position) {
|
|
233
|
+
const generatedLine = position.line - 1;
|
|
234
|
+
let low = 0;
|
|
235
|
+
let high = segments.length - 1;
|
|
236
|
+
let candidate;
|
|
237
|
+
while (low <= high) {
|
|
238
|
+
const mid = low + high >> 1;
|
|
239
|
+
const segment = segments[mid];
|
|
240
|
+
const isAtOrBefore = segment.generatedLine < generatedLine || segment.generatedLine === generatedLine && segment.generatedColumn <= position.column;
|
|
241
|
+
if (isAtOrBefore) {
|
|
242
|
+
candidate = segment;
|
|
243
|
+
low = mid + 1;
|
|
244
|
+
} else {
|
|
245
|
+
high = mid - 1;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return candidate?.generatedLine === generatedLine ? candidate : void 0;
|
|
249
|
+
}
|
|
250
|
+
function decodeIncomingMap(map) {
|
|
251
|
+
const sources = map.sources;
|
|
252
|
+
const segments = decodeSegments(map.mappings);
|
|
253
|
+
return {
|
|
254
|
+
sources,
|
|
255
|
+
sourceRoot: map.sourceRoot,
|
|
256
|
+
sourcesContent: map.sourcesContent,
|
|
257
|
+
originalPositionFor(position) {
|
|
258
|
+
const candidate = findCandidate(segments, position);
|
|
259
|
+
if (!candidate) return;
|
|
260
|
+
return {
|
|
261
|
+
source: sources[candidate.sourceIndex],
|
|
262
|
+
sourceIndex: candidate.sourceIndex,
|
|
263
|
+
line: candidate.sourceLine + 1,
|
|
264
|
+
column: candidate.sourceColumn
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
function decodeOneSegment(state, raw, generatedLine) {
|
|
270
|
+
const col = decodeVLQSegment(raw, 0);
|
|
271
|
+
state.generatedColumn += col.value;
|
|
272
|
+
if (col.next >= raw.length) return void 0;
|
|
273
|
+
const srcIdx = decodeVLQSegment(raw, col.next);
|
|
274
|
+
state.sourceIndex += srcIdx.value;
|
|
275
|
+
const srcLine = decodeVLQSegment(raw, srcIdx.next);
|
|
276
|
+
state.sourceLine += srcLine.value;
|
|
277
|
+
const srcCol = decodeVLQSegment(raw, srcLine.next);
|
|
278
|
+
state.sourceColumn += srcCol.value;
|
|
279
|
+
return {
|
|
280
|
+
generatedLine,
|
|
281
|
+
generatedColumn: state.generatedColumn,
|
|
282
|
+
sourceIndex: state.sourceIndex,
|
|
283
|
+
sourceLine: state.sourceLine,
|
|
284
|
+
sourceColumn: state.sourceColumn
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function decodeSegments(mappings) {
|
|
288
|
+
const segments = [];
|
|
289
|
+
const state = { generatedColumn: 0, sourceIndex: 0, sourceLine: 0, sourceColumn: 0 };
|
|
290
|
+
const lines = mappings.split(";");
|
|
291
|
+
for (const [generatedLine, line] of lines.entries()) {
|
|
292
|
+
state.generatedColumn = 0;
|
|
293
|
+
if (line === "") continue;
|
|
294
|
+
for (const raw of line.split(",")) {
|
|
295
|
+
const segment = decodeOneSegment(state, raw, generatedLine);
|
|
296
|
+
if (segment) segments.push(segment);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return segments;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export { MappingsBuilder, decodeIncomingMap, formatDiagnostic };
|