@navecss/core 0.2.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.
@@ -0,0 +1,94 @@
1
+ import { walkExtendAtoms, hasEscapedCommentOpener, isOnlyInert, hasTopLevelComment, hasUnstrippedTrailingSpace, hasUnstrippedLeadingSpace, lastNonWhitespace, isInert, hasPaddedComment, hasBrokenString, hasUrl, hasStrayCurlyCloser, anchorSelectorList, hasEscapedWhitespace, hasHtmlBreakout, hasTopLevelColon } from './chunk-LADFXRWQ.js';
2
+ import { tokenize, matchBrackets, readItem } from './chunk-NFS2REPQ.js';
3
+
4
+ // src/validate-extend-host-free.ts
5
+ function readSoleBlockItem(text) {
6
+ const tokens = tokenize(text);
7
+ if (tokens.length === 0 || isInert(tokens[0])) return void 0;
8
+ const closerFor = matchBrackets(tokens);
9
+ const item = readItem(tokens, 0, tokens.length, closerFor);
10
+ if (item.end !== tokens.length || item.blockStart === void 0) return void 0;
11
+ const last = tokens.length - 1;
12
+ if (item.blockEnd !== last || tokens[last].type !== "}-token") return void 0;
13
+ if (closerFor[item.blockStart - 1] !== last) return void 0;
14
+ return { item, wrapped: { tokens, closerFor } };
15
+ }
16
+ function isValueRoundTrip(wrapped, from, to, isCustom) {
17
+ const { tokens } = wrapped;
18
+ if (hasBrokenString(tokens, from, to)) return false;
19
+ if (isCustom) return true;
20
+ const last = lastNonWhitespace(tokens, from, to);
21
+ if (last >= from && tokens[last].type === "comment") return false;
22
+ return !hasTopLevelColon(wrapped, from, to);
23
+ }
24
+ function isSoleDeclaration(wrapped, start, end, prop) {
25
+ const { tokens, closerFor } = wrapped;
26
+ const name = tokens[start];
27
+ if (name?.type !== "ident-token" || name.raw !== prop) return false;
28
+ if (tokens[start + 1]?.type !== "colon-token") return false;
29
+ const declaration = readItem(tokens, start, end, closerFor);
30
+ if (declaration.kind !== "declaration") return false;
31
+ if (tokens[declaration.end - 1].type === "semicolon-token") return false;
32
+ if (!isOnlyInert(tokens, declaration.end, end)) return false;
33
+ return isValueRoundTrip(wrapped, start + 2, end, prop.startsWith("--"));
34
+ }
35
+ function isReadTwoWays(prop, value) {
36
+ return hasEscapedCommentOpener(prop) || hasEscapedCommentOpener(value) || hasEscapedWhitespace(prop);
37
+ }
38
+ function isRewrittenByPostcss(prop, value) {
39
+ if (hasHtmlBreakout(prop) || hasHtmlBreakout(value)) return true;
40
+ if (hasUnstrippedTrailingSpace(prop) || hasUnstrippedTrailingSpace(value)) return true;
41
+ return prop.startsWith("--") && value !== value.trimEnd();
42
+ }
43
+ function declarationRefusal(prop, value) {
44
+ if (isReadTwoWays(prop, value)) return "break-out";
45
+ const sole = readSoleBlockItem(`a{${prop}:${value}}`);
46
+ if (sole?.item.kind !== "rule") return "break-out";
47
+ const { blockStart, blockEnd } = sole.item;
48
+ if (!isSoleDeclaration(sole.wrapped, blockStart, blockEnd, prop)) return "break-out";
49
+ return isRewrittenByPostcss(prop, value) ? "rewritten" : void 0;
50
+ }
51
+ function propRefusal(prop) {
52
+ return declarationRefusal(prop, "0");
53
+ }
54
+ function isPreludeUnambiguous(wrapped, from, to) {
55
+ const { tokens } = wrapped;
56
+ return !hasPaddedComment(tokens, from, to) && !hasBrokenString(tokens, from, to) && !hasUrl(tokens, from, to) && !hasStrayCurlyCloser(wrapped, from, to);
57
+ }
58
+ function anchoredSelector(key) {
59
+ let selector;
60
+ try {
61
+ selector = anchorSelectorList(key);
62
+ } catch {
63
+ return void 0;
64
+ }
65
+ const isUnreadable = selector.startsWith("@") || selector.startsWith("--") || hasEscapedCommentOpener(selector);
66
+ return isUnreadable ? void 0 : selector;
67
+ }
68
+ function selectorRefusal(key) {
69
+ const selector = anchoredSelector(key);
70
+ if (selector === void 0) return "break-out";
71
+ const sole = readSoleBlockItem(`${selector}{}`);
72
+ if (sole?.item.kind !== "rule") return "break-out";
73
+ const { tokens } = sole.wrapped;
74
+ const { blockStart, blockEnd } = sole.item;
75
+ const prelude = blockStart - 1;
76
+ const isOneEmptyRule = isOnlyInert(tokens, blockStart, blockEnd) && tokens[lastNonWhitespace(tokens, 0, prelude)]?.type !== "comment" && isPreludeUnambiguous(sole.wrapped, 0, prelude);
77
+ return isOneEmptyRule ? void 0 : "break-out";
78
+ }
79
+ function conditionRefusal(atName, condition) {
80
+ if (hasEscapedCommentOpener(condition)) return "break-out";
81
+ const sole = readSoleBlockItem(`@${atName} ${condition}{}`);
82
+ if (sole?.item.kind !== "at-rule" || sole.item.atKeyword !== atName) return "break-out";
83
+ const { blockStart, blockEnd } = sole.item;
84
+ const prelude = blockStart - 1;
85
+ const isOneBodilessRule = isOnlyInert(sole.wrapped.tokens, blockStart, blockEnd) && !hasTopLevelComment(sole.wrapped, 1, prelude) && isPreludeUnambiguous(sole.wrapped, 1, prelude);
86
+ if (!isOneBodilessRule) return "break-out";
87
+ const isUntrimmed = hasUnstrippedTrailingSpace(condition) || hasUnstrippedLeadingSpace(condition);
88
+ return isUntrimmed ? "rewritten" : void 0;
89
+ }
90
+ function validateExtendAtomsHostFree(extend) {
91
+ walkExtendAtoms(extend, { declarationRefusal, propRefusal, selectorRefusal, conditionRefusal });
92
+ }
93
+
94
+ export { validateExtendAtomsHostFree };