@master/css-compiler 2.0.0-beta.98 → 2.0.0-rc.70
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 +34 -133
- package/dist/browser.d.ts +22 -0
- package/dist/browser.mjs +47 -0
- package/dist/core.d.ts +48 -0
- package/dist/core.mjs +2019 -0
- package/dist/css-transform.d.ts +6 -0
- package/dist/css-transform.mjs +18 -0
- package/dist/index.d.ts +46 -3
- package/dist/index.mjs +394 -10
- package/dist/lexer/imports.d.ts +13 -0
- package/dist/lexer/imports.mjs +44 -0
- package/dist/lexer/source.d.ts +3 -0
- package/dist/lexer/source.mjs +9 -0
- package/dist/lexer/standalone-master.d.ts +21 -0
- package/dist/lexer/standalone-master.mjs +233 -0
- package/dist/lower-css-directives.d.ts +16 -0
- package/dist/lower-css-directives.mjs +969 -0
- package/dist/master-css-manifest.d.ts +14 -0
- package/dist/master-css-manifest.mjs +760 -0
- package/dist/native-declaration.d.ts +2 -0
- package/dist/native-declaration.mjs +25 -0
- package/dist/utils/selectors.d.ts +3 -0
- package/dist/utils/selectors.mjs +55 -0
- package/dist/utils/unquote.d.ts +1 -0
- package/dist/utils/unquote.mjs +10 -0
- package/dist/utils/wrap-at-rules.d.ts +1 -0
- package/dist/utils/wrap-at-rules.mjs +10 -0
- package/package.json +1 -1
- package/dist/compiler.d.ts +0 -18
- package/dist/extract.d.ts +0 -3
- package/dist/index.cjs +0 -10
- package/dist/options/index.d.ts +0 -17
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { removeSourceRanges, escapeRegExp } from '@master/css-lexer';
|
|
2
|
+
import { findAtRuleStatementEnd } from './source.mjs';
|
|
3
|
+
|
|
4
|
+
const STANDALONE_CSS_DIRECTIVE_NAMES = new Set([
|
|
5
|
+
'master',
|
|
6
|
+
'source',
|
|
7
|
+
'safelist',
|
|
8
|
+
'blocklist',
|
|
9
|
+
'preserve'
|
|
10
|
+
]);
|
|
11
|
+
function isIdentChar(char) {
|
|
12
|
+
return Boolean(char && /[-_a-zA-Z0-9]/.test(char));
|
|
13
|
+
}
|
|
14
|
+
function parseQuotedStrings(source) {
|
|
15
|
+
const values = [];
|
|
16
|
+
let quote = '';
|
|
17
|
+
let value = '';
|
|
18
|
+
for(let index = 0; index < source.length; index++){
|
|
19
|
+
const char = source[index];
|
|
20
|
+
if (!quote) {
|
|
21
|
+
if (char === '"' || char === '\'') {
|
|
22
|
+
quote = char;
|
|
23
|
+
value = '';
|
|
24
|
+
}
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (char === '\\') {
|
|
28
|
+
value += source[index + 1] || '';
|
|
29
|
+
index++;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (char === quote) {
|
|
33
|
+
values.push(value);
|
|
34
|
+
quote = '';
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
value += char;
|
|
38
|
+
}
|
|
39
|
+
return values;
|
|
40
|
+
}
|
|
41
|
+
function parseUnquotedWords(source) {
|
|
42
|
+
const words = [];
|
|
43
|
+
let quote = '';
|
|
44
|
+
let comment = false;
|
|
45
|
+
let word = '';
|
|
46
|
+
for(let index = 0; index < source.length; index++){
|
|
47
|
+
const char = source[index];
|
|
48
|
+
const next = source[index + 1];
|
|
49
|
+
if (comment) {
|
|
50
|
+
if (char === '*' && next === '/') {
|
|
51
|
+
comment = false;
|
|
52
|
+
index++;
|
|
53
|
+
}
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (quote) {
|
|
57
|
+
if (char === '\\') index++;
|
|
58
|
+
else if (char === quote) quote = '';
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (char === '/' && next === '*') {
|
|
62
|
+
comment = true;
|
|
63
|
+
index++;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (char === '"' || char === '\'') {
|
|
67
|
+
quote = char;
|
|
68
|
+
if (word) {
|
|
69
|
+
words.push(word);
|
|
70
|
+
word = '';
|
|
71
|
+
}
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (isIdentChar(char)) {
|
|
75
|
+
word += char;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (word) {
|
|
79
|
+
words.push(word);
|
|
80
|
+
word = '';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (word) words.push(word);
|
|
84
|
+
return words;
|
|
85
|
+
}
|
|
86
|
+
function wildcardToRegExp(source) {
|
|
87
|
+
return new RegExp(`^${source.split(/([*?])/g).map((part)=>{
|
|
88
|
+
if (part === '*') return '.*';
|
|
89
|
+
if (part === '?') return '.';
|
|
90
|
+
return escapeRegExp(part);
|
|
91
|
+
}).join('')}$`);
|
|
92
|
+
}
|
|
93
|
+
function normalizeBlocklistPattern(pattern) {
|
|
94
|
+
return /[*?]/.test(pattern) ? wildcardToRegExp(pattern) : pattern;
|
|
95
|
+
}
|
|
96
|
+
function addUnique(target, values) {
|
|
97
|
+
for (const value of values){
|
|
98
|
+
if (!target.includes(value)) {
|
|
99
|
+
target.push(value);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function createCSSDirectiveExtractionPolicy() {
|
|
104
|
+
return {
|
|
105
|
+
include: [],
|
|
106
|
+
exclude: [],
|
|
107
|
+
safelist: [],
|
|
108
|
+
blocklist: [],
|
|
109
|
+
preserveNative: false
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function mergeCSSDirectiveExtractionPolicy(...policies) {
|
|
113
|
+
const merged = createCSSDirectiveExtractionPolicy();
|
|
114
|
+
for (const policy of policies){
|
|
115
|
+
if (!policy) continue;
|
|
116
|
+
addUnique(merged.include, policy.include || []);
|
|
117
|
+
addUnique(merged.exclude, policy.exclude || []);
|
|
118
|
+
addUnique(merged.safelist, policy.safelist || []);
|
|
119
|
+
addUnique(merged.blocklist, policy.blocklist || []);
|
|
120
|
+
merged.preserveNative ||= Boolean(policy.preserveNative);
|
|
121
|
+
}
|
|
122
|
+
return merged;
|
|
123
|
+
}
|
|
124
|
+
function parseAtRuleName(source, start) {
|
|
125
|
+
let cursor = start + 1;
|
|
126
|
+
while(isIdentChar(source[cursor]))cursor++;
|
|
127
|
+
return source.slice(start + 1, cursor);
|
|
128
|
+
}
|
|
129
|
+
function parseStandaloneCSSDirectiveStatement(source, start, atRuleName) {
|
|
130
|
+
const end = findAtRuleStatementEnd(source, start);
|
|
131
|
+
if (end === -1) return;
|
|
132
|
+
const statement = source.slice(start, end);
|
|
133
|
+
const prelude = statement.replace(new RegExp(`^@${atRuleName}\\b`), '').replace(/;$/, '');
|
|
134
|
+
if (atRuleName === 'master' && prelude.trim()) return;
|
|
135
|
+
const name = atRuleName === 'master' ? '' : atRuleName;
|
|
136
|
+
return {
|
|
137
|
+
start,
|
|
138
|
+
end,
|
|
139
|
+
atRuleName,
|
|
140
|
+
name,
|
|
141
|
+
statement,
|
|
142
|
+
args: parseQuotedStrings(prelude),
|
|
143
|
+
modifiers: parseUnquotedWords(prelude)
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function findStandaloneCSSDirectiveStatements(source, filename = 'master.css') {
|
|
147
|
+
const statements = [];
|
|
148
|
+
let quote = '';
|
|
149
|
+
let comment = false;
|
|
150
|
+
let depth = 0;
|
|
151
|
+
for(let index = 0; index < source.length; index++){
|
|
152
|
+
const char = source[index];
|
|
153
|
+
const next = source[index + 1];
|
|
154
|
+
if (comment) {
|
|
155
|
+
if (char === '*' && next === '/') {
|
|
156
|
+
comment = false;
|
|
157
|
+
index++;
|
|
158
|
+
}
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (quote) {
|
|
162
|
+
if (char === '\\') {
|
|
163
|
+
index++;
|
|
164
|
+
} else if (char === quote) {
|
|
165
|
+
quote = '';
|
|
166
|
+
}
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (char === '/' && next === '*') {
|
|
170
|
+
comment = true;
|
|
171
|
+
index++;
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (char === '"' || char === '\'') {
|
|
175
|
+
quote = char;
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (char === '{') {
|
|
179
|
+
depth++;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (char === '}') {
|
|
183
|
+
depth--;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (depth !== 0 || char !== '@') continue;
|
|
187
|
+
const name = parseAtRuleName(source, index);
|
|
188
|
+
if (!STANDALONE_CSS_DIRECTIVE_NAMES.has(name)) continue;
|
|
189
|
+
if (isIdentChar(source[index + name.length + 1])) continue;
|
|
190
|
+
const statement = parseStandaloneCSSDirectiveStatement(source, index, name);
|
|
191
|
+
if (!statement) continue;
|
|
192
|
+
statements.push(statement);
|
|
193
|
+
index = statement.end - 1;
|
|
194
|
+
}
|
|
195
|
+
return statements;
|
|
196
|
+
}
|
|
197
|
+
function findStandaloneMasterDirectiveStatements(source, filename = 'master.css') {
|
|
198
|
+
return findStandaloneCSSDirectiveStatements(source, filename).filter((statement)=>statement.atRuleName === 'master');
|
|
199
|
+
}
|
|
200
|
+
function collectStandaloneCSSDirectiveExtractionPolicy(source, filename = 'master.css') {
|
|
201
|
+
const policy = createCSSDirectiveExtractionPolicy();
|
|
202
|
+
for (const statement of findStandaloneCSSDirectiveStatements(source, filename)){
|
|
203
|
+
switch(statement.atRuleName){
|
|
204
|
+
case 'source':
|
|
205
|
+
if (statement.modifiers.includes('not')) {
|
|
206
|
+
policy.exclude.push(...statement.args);
|
|
207
|
+
} else {
|
|
208
|
+
policy.include.push(...statement.args);
|
|
209
|
+
}
|
|
210
|
+
break;
|
|
211
|
+
case 'safelist':
|
|
212
|
+
policy.safelist.push(...statement.args.flatMap((arg)=>arg.split(/\s+/).filter(Boolean)));
|
|
213
|
+
break;
|
|
214
|
+
case 'blocklist':
|
|
215
|
+
policy.blocklist.push(...statement.args.flatMap((arg)=>arg.split(/\s+/).filter(Boolean)).map(normalizeBlocklistPattern));
|
|
216
|
+
break;
|
|
217
|
+
case 'preserve':
|
|
218
|
+
if (statement.modifiers.includes('native')) {
|
|
219
|
+
policy.preserveNative = true;
|
|
220
|
+
}
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return policy;
|
|
225
|
+
}
|
|
226
|
+
function removeStandaloneCSSDirectives(source, filename = 'master.css') {
|
|
227
|
+
return removeSourceRanges(source, findStandaloneCSSDirectiveStatements(source, filename));
|
|
228
|
+
}
|
|
229
|
+
function removeStandaloneMasterDirectives(source, filename = 'master.css') {
|
|
230
|
+
return removeSourceRanges(source, findStandaloneMasterDirectiveStatements(source, filename));
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export { collectStandaloneCSSDirectiveExtractionPolicy, createCSSDirectiveExtractionPolicy, findStandaloneCSSDirectiveStatements, findStandaloneMasterDirectiveStatements, mergeCSSDirectiveExtractionPolicy, removeStandaloneCSSDirectives, removeStandaloneMasterDirectives };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type CSSDirectiveManifestInput, type CSSDirectiveResult } from '@master/css-schema/css-directives';
|
|
2
|
+
import type { MasterCSSManifest } from '@master/css-schema/manifest';
|
|
3
|
+
export interface LowerCSSDirectivesOptions {
|
|
4
|
+
baseManifest?: MasterCSSManifest;
|
|
5
|
+
resolutionManifest?: MasterCSSManifest;
|
|
6
|
+
onWarning?: (warning: string) => void;
|
|
7
|
+
}
|
|
8
|
+
export interface LowerCSSDirectivesResult {
|
|
9
|
+
input: CSSDirectiveManifestInput;
|
|
10
|
+
manifest: MasterCSSManifest;
|
|
11
|
+
warnings: string[];
|
|
12
|
+
generatedCSS: string;
|
|
13
|
+
}
|
|
14
|
+
type CSSDirectiveManifestInputSource = CSSDirectiveResult | CSSDirectiveManifestInput;
|
|
15
|
+
export default function lowerCSSDirectives(input: CSSDirectiveManifestInputSource, options?: LowerCSSDirectivesOptions): LowerCSSDirectivesResult;
|
|
16
|
+
export {};
|