@lass-lang/core 0.0.1
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/CHANGELOG.md +23 -0
- package/LICENSE +21 -0
- package/README.md +93 -0
- package/dist/constants.d.ts +32 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +32 -0
- package/dist/constants.js.map +1 -0
- package/dist/context-tracker.d.ts +46 -0
- package/dist/context-tracker.d.ts.map +1 -0
- package/dist/context-tracker.js +76 -0
- package/dist/context-tracker.js.map +1 -0
- package/dist/errors.d.ts +80 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +81 -0
- package/dist/errors.js.map +1 -0
- package/dist/helpers.d.ts +24 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +32 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -0
- package/dist/scanner.d.ts +326 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +815 -0
- package/dist/scanner.js.map +1 -0
- package/dist/scope-tracker.d.ts +160 -0
- package/dist/scope-tracker.d.ts.map +1 -0
- package/dist/scope-tracker.js +376 -0
- package/dist/scope-tracker.js.map +1 -0
- package/dist/transpiler.d.ts +153 -0
- package/dist/transpiler.d.ts.map +1 -0
- package/dist/transpiler.js +650 -0
- package/dist/transpiler.js.map +1 -0
- package/dist/types.d.ts +55 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,650 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transpiler pipeline functions for @lass-lang/core
|
|
3
|
+
*
|
|
4
|
+
* Each function represents a step in the transpilation story.
|
|
5
|
+
* See index.ts for the main entry point that orchestrates these steps.
|
|
6
|
+
*/
|
|
7
|
+
import { Scanner } from './scanner.js';
|
|
8
|
+
import { cutByBraces, findPropertyValue } from './scope-tracker.js';
|
|
9
|
+
import { escapeForTemplateLiteral, escapeForJs } from './helpers.js';
|
|
10
|
+
import { LASS_SCRIPT_EXPRESSION_HELPER, LASS_SCRIPT_LOOKUP_HELPER } from './constants.js';
|
|
11
|
+
import { createContextState, updateContextState, isInProtectedContext } from './context-tracker.js';
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// STEP 1: ZONE DETECTION
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Step 1: Detect and split zones.
|
|
17
|
+
*
|
|
18
|
+
* Finds the --- separator and splits source into preamble and CSS zones.
|
|
19
|
+
* If no separator, entire source is the CSS zone (pure CSS passthrough).
|
|
20
|
+
*
|
|
21
|
+
* @param source - Raw Lass source code
|
|
22
|
+
* @param options - Transpile options (filename for errors)
|
|
23
|
+
* @returns Detected zones with preamble and cssZone
|
|
24
|
+
*/
|
|
25
|
+
export function detectZones(source, options) {
|
|
26
|
+
const scanner = new Scanner(source, { filename: options.filename });
|
|
27
|
+
const zones = scanner.findSeparator();
|
|
28
|
+
return {
|
|
29
|
+
preamble: zones.preamble,
|
|
30
|
+
cssZone: zones.cssZone,
|
|
31
|
+
hasSeparator: zones.hasSeparator,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// STEP 2: COMMENT STRIPPING
|
|
36
|
+
// ============================================================================
|
|
37
|
+
/**
|
|
38
|
+
* Step 2: Strip // comments from CSS zone.
|
|
39
|
+
*
|
|
40
|
+
* Story 4.4: Single-line comment stripping.
|
|
41
|
+
* Removes // comments while respecting protected contexts (strings, url(), block comments).
|
|
42
|
+
*
|
|
43
|
+
* @param cssZone - The CSS zone content
|
|
44
|
+
* @returns CSS zone with // comments removed
|
|
45
|
+
*/
|
|
46
|
+
export function stripLineComments(cssZone) {
|
|
47
|
+
return Scanner.stripLineCommentsStatic(cssZone);
|
|
48
|
+
}
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// STEP 3a: STYLE LOOKUP SHORTHAND NORMALIZATION
|
|
51
|
+
// ============================================================================
|
|
52
|
+
/**
|
|
53
|
+
* Step 3a: Normalize @prop shorthands to @(prop) form.
|
|
54
|
+
*
|
|
55
|
+
* Story 4.2: Style Lookup Shorthand
|
|
56
|
+
*
|
|
57
|
+
* Finds @prop patterns in CSS value position and converts them to @(prop).
|
|
58
|
+
* This runs BEFORE @(prop) resolution so all lookups are handled uniformly.
|
|
59
|
+
*
|
|
60
|
+
* Detection rules:
|
|
61
|
+
* - @prop shorthand only works when identifier starts with a letter [a-zA-Z]
|
|
62
|
+
* - NOT detected inside {{ }} script blocks
|
|
63
|
+
* - NOT detected inside protected contexts: strings, comments, url()
|
|
64
|
+
*
|
|
65
|
+
* @param cssZone - The CSS zone content
|
|
66
|
+
* @returns CSS zone with @prop normalized to @(prop)
|
|
67
|
+
*/
|
|
68
|
+
export function normalizeStyleLookupShorthands(cssZone) {
|
|
69
|
+
if (!cssZone) {
|
|
70
|
+
return cssZone;
|
|
71
|
+
}
|
|
72
|
+
const shorthands = Scanner.findStyleLookupShorthandsStatic(cssZone);
|
|
73
|
+
if (shorthands.length === 0) {
|
|
74
|
+
return cssZone;
|
|
75
|
+
}
|
|
76
|
+
// Process from end to start so indices remain valid
|
|
77
|
+
let result = cssZone;
|
|
78
|
+
for (let i = shorthands.length - 1; i >= 0; i--) {
|
|
79
|
+
const shorthand = shorthands[i];
|
|
80
|
+
const { propName, startIndex, endIndex } = shorthand;
|
|
81
|
+
// Replace @prop with @(prop)
|
|
82
|
+
result = result.slice(0, startIndex) + `@(${propName})` + result.slice(endIndex);
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// STEP 3b: PROPERTY ACCESSOR RESOLUTION
|
|
88
|
+
// ============================================================================
|
|
89
|
+
/**
|
|
90
|
+
* Step 3b: Resolve @(prop) accessors in CSS zone.
|
|
91
|
+
*
|
|
92
|
+
* Story 3.2: Basic Property Lookup
|
|
93
|
+
* Story 3.3: Lookup in {{ }} Context
|
|
94
|
+
* Refactored: Changed from @prop to @(prop) for unambiguous syntax
|
|
95
|
+
*
|
|
96
|
+
* Finds @(prop) patterns in CSS value position and resolves them to their
|
|
97
|
+
* previously-declared values using scope tracking utilities.
|
|
98
|
+
*
|
|
99
|
+
* Resolution rules:
|
|
100
|
+
* - Property found in CSS context -> Replace @(prop) with resolved value
|
|
101
|
+
* - Property found in JS context (inside {{ }}) -> Replace with quoted value
|
|
102
|
+
* - Property not found -> Preserve @(prop) unchanged (PostCSS/future CSS compatibility)
|
|
103
|
+
*
|
|
104
|
+
* This is Phase 1 of transpilation and runs BEFORE {{ }} processing.
|
|
105
|
+
*
|
|
106
|
+
* @param cssZone - The CSS zone content
|
|
107
|
+
* @param options - Transpile options (filename for errors)
|
|
108
|
+
* @returns CSS zone with @(prop) accessors resolved (or preserved if not found)
|
|
109
|
+
*/
|
|
110
|
+
export function resolvePropertyAccessors(cssZone, _options) {
|
|
111
|
+
if (!cssZone) {
|
|
112
|
+
return cssZone;
|
|
113
|
+
}
|
|
114
|
+
// Use static method to avoid creating unnecessary Scanner instance
|
|
115
|
+
const accessors = Scanner.findPropertyAccessorsStatic(cssZone);
|
|
116
|
+
if (accessors.length === 0) {
|
|
117
|
+
return cssZone;
|
|
118
|
+
}
|
|
119
|
+
// Get scope slices for property lookup
|
|
120
|
+
const { slices } = cutByBraces(cssZone);
|
|
121
|
+
// Build a map of character positions to slice indices
|
|
122
|
+
// cutByBraces splits at braces, so we need to track where each slice starts
|
|
123
|
+
// Use openedBy to determine brace size: '{{' = 2, '@{' = 2, '{' = 1, null = 0
|
|
124
|
+
const sliceStartPositions = [];
|
|
125
|
+
let pos = 0;
|
|
126
|
+
for (let s = 0; s < slices.length; s++) {
|
|
127
|
+
sliceStartPositions.push(pos);
|
|
128
|
+
pos += slices[s].content.length;
|
|
129
|
+
// Add brace characters between slices (except after last)
|
|
130
|
+
if (s < slices.length - 1) {
|
|
131
|
+
// Look at the NEXT slice to determine what brace opened it
|
|
132
|
+
const nextSlice = slices[s + 1];
|
|
133
|
+
switch (nextSlice.openedBy) {
|
|
134
|
+
case '{{':
|
|
135
|
+
case '@{':
|
|
136
|
+
pos += 2; // {{ or @{ are 2 chars
|
|
137
|
+
break;
|
|
138
|
+
case '{':
|
|
139
|
+
pos += 1; // { is 1 char
|
|
140
|
+
break;
|
|
141
|
+
default:
|
|
142
|
+
// Closing brace - need to determine size from current slice's context
|
|
143
|
+
// If current was opened by {{ → closing is }} (2 chars)
|
|
144
|
+
// If current was opened by @{ → closing is } (1 char)
|
|
145
|
+
// If current was opened by { → closing is } (1 char)
|
|
146
|
+
const currentSlice = slices[s];
|
|
147
|
+
if (currentSlice.openedBy === '{{') {
|
|
148
|
+
pos += 2; // }}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
pos += 1; // }
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// Build result by replacing @(prop) with resolved values (or preserving)
|
|
157
|
+
// Process from end to start so indices remain valid
|
|
158
|
+
let result = cssZone;
|
|
159
|
+
for (let i = accessors.length - 1; i >= 0; i--) {
|
|
160
|
+
const accessor = accessors[i];
|
|
161
|
+
const { propName, startIndex, endIndex } = accessor;
|
|
162
|
+
// Find which slice contains this @(prop)
|
|
163
|
+
let sliceIndex = 0;
|
|
164
|
+
for (let s = slices.length - 1; s >= 0; s--) {
|
|
165
|
+
if (startIndex >= sliceStartPositions[s]) {
|
|
166
|
+
sliceIndex = s;
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Position within the slice (for self-reference protection)
|
|
171
|
+
const positionInSlice = startIndex - sliceStartPositions[sliceIndex];
|
|
172
|
+
// Look up the property value
|
|
173
|
+
const value = findPropertyValue(propName, slices, sliceIndex, positionInSlice);
|
|
174
|
+
// Only replace if we found a value (non-empty string)
|
|
175
|
+
// If not found, preserve the original @(prop) (PostCSS/future CSS compatibility)
|
|
176
|
+
if (value !== '') {
|
|
177
|
+
// Story 3.3: If @(prop) is inside a JS-type slice, quote the value
|
|
178
|
+
const slice = slices[sliceIndex];
|
|
179
|
+
const replacement = slice.type === 'js'
|
|
180
|
+
? `"${escapeForJs(value)}"`
|
|
181
|
+
: value;
|
|
182
|
+
result = result.slice(0, startIndex) + replacement + result.slice(endIndex);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return result;
|
|
186
|
+
}
|
|
187
|
+
// ============================================================================
|
|
188
|
+
// STEP 4: DOLLAR VARIABLE RESOLUTION
|
|
189
|
+
// ============================================================================
|
|
190
|
+
/**
|
|
191
|
+
* Step 4: Replace $param variables with __lassScriptLookup() calls.
|
|
192
|
+
*
|
|
193
|
+
* Story 4.1: Variable Substitution
|
|
194
|
+
*
|
|
195
|
+
* Finds $param patterns in CSS zone and converts them to helper function calls.
|
|
196
|
+
* This enables $-prefixed variables from the preamble to be substituted into CSS
|
|
197
|
+
* with proper handling of null (-> 'unset') and undefined/missing (-> preserved).
|
|
198
|
+
*
|
|
199
|
+
* Protected contexts (strings, url(), comments) are skipped - $param inside these
|
|
200
|
+
* remains as literal text. Use {{ $param }} for dynamic content in protected contexts.
|
|
201
|
+
*
|
|
202
|
+
* @param cssZone - The CSS zone content
|
|
203
|
+
* @param _options - Transpile options (filename for errors)
|
|
204
|
+
* @returns Result with modified CSS zone and flag indicating if helpers needed
|
|
205
|
+
*/
|
|
206
|
+
export function resolveDollarVariables(cssZone, _options) {
|
|
207
|
+
if (!cssZone) {
|
|
208
|
+
return { cssZone, hasDollarVariables: false };
|
|
209
|
+
}
|
|
210
|
+
// Use static method to find all $param occurrences
|
|
211
|
+
const variables = Scanner.findDollarVariablesStatic(cssZone);
|
|
212
|
+
if (variables.length === 0) {
|
|
213
|
+
return { cssZone, hasDollarVariables: false };
|
|
214
|
+
}
|
|
215
|
+
// Process from end to start so indices remain valid
|
|
216
|
+
let result = cssZone;
|
|
217
|
+
for (let i = variables.length - 1; i >= 0; i--) {
|
|
218
|
+
const variable = variables[i];
|
|
219
|
+
const { varName, startIndex, endIndex } = variable;
|
|
220
|
+
// Replace $varName with ${__lassScriptLookup('name', () => $varName)}
|
|
221
|
+
// The name parameter is without the $ prefix (helper adds it back for preserved output)
|
|
222
|
+
const nameWithoutDollar = varName.slice(1); // Remove leading $
|
|
223
|
+
const replacement = `\${__lassScriptLookup('${nameWithoutDollar}', () => ${varName})}`;
|
|
224
|
+
result = result.slice(0, startIndex) + replacement + result.slice(endIndex);
|
|
225
|
+
}
|
|
226
|
+
return { cssZone: result, hasDollarVariables: true };
|
|
227
|
+
}
|
|
228
|
+
// ============================================================================
|
|
229
|
+
// STEP 5a: STYLE BLOCK TRANSLATION
|
|
230
|
+
// ============================================================================
|
|
231
|
+
/**
|
|
232
|
+
* Normalizes style block content by trimming and dedenting.
|
|
233
|
+
*
|
|
234
|
+
* Single-line (no newlines): Trim leading/trailing whitespace.
|
|
235
|
+
* Multi-line:
|
|
236
|
+
* - Dedent all lines by the minimum indentation found
|
|
237
|
+
* - Trim leading and trailing whitespace
|
|
238
|
+
*
|
|
239
|
+
* @param content - Raw content from inside @{ }
|
|
240
|
+
* @returns Normalized content
|
|
241
|
+
*/
|
|
242
|
+
export function normalizeStyleBlockContent(content) {
|
|
243
|
+
// Single-line: just trim
|
|
244
|
+
if (!content.includes('\n')) {
|
|
245
|
+
return content.trim();
|
|
246
|
+
}
|
|
247
|
+
const lines = content.split('\n');
|
|
248
|
+
// Find minimum indent of non-empty lines
|
|
249
|
+
let minIndent = Infinity;
|
|
250
|
+
for (const line of lines) {
|
|
251
|
+
if (line.trim() !== '') {
|
|
252
|
+
const leadingSpaces = line.match(/^[ \t]*/)?.[0].length ?? 0;
|
|
253
|
+
minIndent = Math.min(minIndent, leadingSpaces);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (minIndent === Infinity) {
|
|
257
|
+
minIndent = 0;
|
|
258
|
+
}
|
|
259
|
+
// Dedent all lines
|
|
260
|
+
const dedented = lines.map(line => {
|
|
261
|
+
if (line.trim() === '') {
|
|
262
|
+
return ''; // Empty lines become empty
|
|
263
|
+
}
|
|
264
|
+
return line.slice(minIndent);
|
|
265
|
+
});
|
|
266
|
+
// Join and trim
|
|
267
|
+
return dedented.join('\n').trim();
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Translates @{ } style blocks to JS template literals.
|
|
271
|
+
*
|
|
272
|
+
* Story 5.1: Style Block Syntax
|
|
273
|
+
*
|
|
274
|
+
* @{ } is purely delimiter translation:
|
|
275
|
+
* - @{ → backtick (`)
|
|
276
|
+
* - } (matching @{) → backtick (`)
|
|
277
|
+
* - {{ }} inside @{ } → ${ } with __lassScriptExpression helper
|
|
278
|
+
* - $param inside @{ } → ${__lassScriptLookup(...)} for proper null/undefined handling
|
|
279
|
+
*
|
|
280
|
+
* This function handles brace matching to find the correct closing }.
|
|
281
|
+
* Nested braces (from object literals, ternaries, etc.) are tracked.
|
|
282
|
+
*
|
|
283
|
+
* Protected contexts (where @{ is NOT translated):
|
|
284
|
+
* - Inside string literals ("..." or '...')
|
|
285
|
+
* - Inside block comments
|
|
286
|
+
* - Note: url() is NOT protected - @{ inside url() IS translated
|
|
287
|
+
*
|
|
288
|
+
* @param text - JS code containing @{ } style blocks
|
|
289
|
+
* @returns Result with translated text and flag for $param usage
|
|
290
|
+
*/
|
|
291
|
+
export function translateStyleBlocks(text) {
|
|
292
|
+
if (!text || !text.includes('@{')) {
|
|
293
|
+
return { text, hasDollarVariables: false };
|
|
294
|
+
}
|
|
295
|
+
const state = createContextState();
|
|
296
|
+
let result = '';
|
|
297
|
+
let i = 0;
|
|
298
|
+
let hasDollarVars = false;
|
|
299
|
+
while (i < text.length) {
|
|
300
|
+
const char = text[i];
|
|
301
|
+
const nextChar = text[i + 1];
|
|
302
|
+
// Update context state for strings and block comments
|
|
303
|
+
const consumed = updateContextState(text, i, state);
|
|
304
|
+
if (consumed === 2) {
|
|
305
|
+
result += text.slice(i, i + 2);
|
|
306
|
+
i += 2;
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
// Skip string quote characters
|
|
310
|
+
if (char === '"' || char === "'") {
|
|
311
|
+
result += char;
|
|
312
|
+
i++;
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
// Skip if in protected context
|
|
316
|
+
if (isInProtectedContext(state)) {
|
|
317
|
+
result += char;
|
|
318
|
+
i++;
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
// Check for @{ style block opener
|
|
322
|
+
if (char === '@' && nextChar === '{') {
|
|
323
|
+
// Found style block - find matching }
|
|
324
|
+
const closeIndex = findStyleBlockClose(text, i + 2);
|
|
325
|
+
if (closeIndex === -1) {
|
|
326
|
+
// No matching } found - treat as literal text
|
|
327
|
+
result += '@{';
|
|
328
|
+
i += 2;
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
// Extract content between @{ and }
|
|
332
|
+
const content = text.slice(i + 2, closeIndex);
|
|
333
|
+
// Normalize whitespace: dedent and trim boundary empty lines
|
|
334
|
+
const normalizedContent = normalizeStyleBlockContent(content);
|
|
335
|
+
// Recursively translate any nested @{ } inside
|
|
336
|
+
const nestedResult = translateStyleBlocks(normalizedContent);
|
|
337
|
+
if (nestedResult.hasDollarVariables) {
|
|
338
|
+
hasDollarVars = true;
|
|
339
|
+
}
|
|
340
|
+
// Translate $param to ${__lassScriptLookup(...)} inside the style block content
|
|
341
|
+
const dollarResult = translateDollarVariablesInStyleBlock(nestedResult.text);
|
|
342
|
+
if (dollarResult.hasDollarVariables) {
|
|
343
|
+
hasDollarVars = true;
|
|
344
|
+
}
|
|
345
|
+
// Translate {{ }} to ${__lassScriptExpression(...)} inside the style block content
|
|
346
|
+
const finalContent = translateMustacheToInterpolation(dollarResult.text);
|
|
347
|
+
// Output as template literal
|
|
348
|
+
result += '`' + finalContent + '`';
|
|
349
|
+
i = closeIndex + 1;
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
result += char;
|
|
353
|
+
i++;
|
|
354
|
+
}
|
|
355
|
+
return { text: result, hasDollarVariables: hasDollarVars };
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Finds the matching closing } for a style block.
|
|
359
|
+
*
|
|
360
|
+
* Tracks brace depth to handle nested braces from:
|
|
361
|
+
* - Object literals: { key: value }
|
|
362
|
+
* - Ternary expressions: { ... } in conditionals
|
|
363
|
+
* - CSS blocks inside {{ }}
|
|
364
|
+
*
|
|
365
|
+
* But {{ and }} are treated specially - they don't affect brace depth.
|
|
366
|
+
*
|
|
367
|
+
* @param text - Full text to scan
|
|
368
|
+
* @param startIndex - Index right after @{ (first char of content)
|
|
369
|
+
* @returns Index of closing } or -1 if not found
|
|
370
|
+
*/
|
|
371
|
+
function findStyleBlockClose(text, startIndex) {
|
|
372
|
+
const state = createContextState();
|
|
373
|
+
let braceDepth = 0;
|
|
374
|
+
let i = startIndex;
|
|
375
|
+
while (i < text.length) {
|
|
376
|
+
const char = text[i];
|
|
377
|
+
const nextChar = text[i + 1];
|
|
378
|
+
// Update context state for strings and block comments
|
|
379
|
+
const consumed = updateContextState(text, i, state);
|
|
380
|
+
if (consumed === 2) {
|
|
381
|
+
i += 2;
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
// Skip string quote characters
|
|
385
|
+
if (char === '"' || char === "'") {
|
|
386
|
+
i++;
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
// Skip if in protected context
|
|
390
|
+
if (isInProtectedContext(state)) {
|
|
391
|
+
i++;
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
// Handle {{ - don't count as single {
|
|
395
|
+
if (char === '{' && nextChar === '{') {
|
|
396
|
+
i += 2;
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
// Handle }} - don't count as single }
|
|
400
|
+
if (char === '}' && nextChar === '}') {
|
|
401
|
+
i += 2;
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
// Handle nested @{ - increase depth
|
|
405
|
+
if (char === '@' && nextChar === '{') {
|
|
406
|
+
braceDepth++;
|
|
407
|
+
i += 2;
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
// Single { increases depth
|
|
411
|
+
if (char === '{') {
|
|
412
|
+
braceDepth++;
|
|
413
|
+
i++;
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
// Single } decreases depth or closes style block
|
|
417
|
+
if (char === '}') {
|
|
418
|
+
if (braceDepth === 0) {
|
|
419
|
+
// This is our closing }
|
|
420
|
+
return i;
|
|
421
|
+
}
|
|
422
|
+
braceDepth--;
|
|
423
|
+
i++;
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
i++;
|
|
427
|
+
}
|
|
428
|
+
// No matching } found
|
|
429
|
+
return -1;
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Gets the leading whitespace (indent) at a given position by looking backwards to line start.
|
|
433
|
+
*
|
|
434
|
+
* @param text - The full text
|
|
435
|
+
* @param pos - Position to find indent for
|
|
436
|
+
* @returns The whitespace string at the start of the line, or empty string if none
|
|
437
|
+
*/
|
|
438
|
+
function getIndentAtPosition(text, pos) {
|
|
439
|
+
// Find the start of the line containing this position
|
|
440
|
+
let lineStart = pos;
|
|
441
|
+
while (lineStart > 0 && text[lineStart - 1] !== '\n') {
|
|
442
|
+
lineStart--;
|
|
443
|
+
}
|
|
444
|
+
// Extract leading whitespace
|
|
445
|
+
let indent = '';
|
|
446
|
+
for (let i = lineStart; i < pos; i++) {
|
|
447
|
+
const char = text[i];
|
|
448
|
+
if (char === ' ' || char === '\t') {
|
|
449
|
+
indent += char;
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
// Non-whitespace found - this is the effective indent up to this point
|
|
453
|
+
break;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return indent;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Translates {{ expr }} to ${__lassScriptExpression(expr, indent)} inside style block content.
|
|
460
|
+
*
|
|
461
|
+
* This is applied after @{ } is translated to backticks, so any {{ }} inside
|
|
462
|
+
* becomes template literal interpolations with proper array/null handling.
|
|
463
|
+
*
|
|
464
|
+
* Indent is calculated from the position of {{ within the style block content
|
|
465
|
+
* to enable proper multi-line re-indentation at runtime.
|
|
466
|
+
*
|
|
467
|
+
* @param text - Content inside a style block
|
|
468
|
+
* @returns Text with {{ }} translated to ${__lassScriptExpression(...)}
|
|
469
|
+
*/
|
|
470
|
+
function translateMustacheToInterpolation(text) {
|
|
471
|
+
let result = '';
|
|
472
|
+
let i = 0;
|
|
473
|
+
while (i < text.length) {
|
|
474
|
+
// Check for {{
|
|
475
|
+
if (text[i] === '{' && text[i + 1] === '{') {
|
|
476
|
+
// Find matching }}
|
|
477
|
+
let depth = 0;
|
|
478
|
+
let j = i + 2;
|
|
479
|
+
while (j < text.length - 1) {
|
|
480
|
+
if (text[j] === '{') {
|
|
481
|
+
depth++;
|
|
482
|
+
}
|
|
483
|
+
else if (text[j] === '}') {
|
|
484
|
+
if (depth === 0 && text[j + 1] === '}') {
|
|
485
|
+
// Found closing }}
|
|
486
|
+
break;
|
|
487
|
+
}
|
|
488
|
+
depth--;
|
|
489
|
+
}
|
|
490
|
+
j++;
|
|
491
|
+
}
|
|
492
|
+
if (j < text.length - 1 && text[j] === '}' && text[j + 1] === '}') {
|
|
493
|
+
// Extract expression and wrap with helper
|
|
494
|
+
const expr = text.slice(i + 2, j).trim();
|
|
495
|
+
// Calculate indent at {{ position for multi-line re-indentation
|
|
496
|
+
const indent = getIndentAtPosition(text, i);
|
|
497
|
+
if (indent) {
|
|
498
|
+
result += '${__lassScriptExpression(' + expr + ', "' + indent + '")}';
|
|
499
|
+
}
|
|
500
|
+
else {
|
|
501
|
+
result += '${__lassScriptExpression(' + expr + ')}';
|
|
502
|
+
}
|
|
503
|
+
i = j + 2;
|
|
504
|
+
continue;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
result += text[i];
|
|
508
|
+
i++;
|
|
509
|
+
}
|
|
510
|
+
return result;
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Translates $param variables to ${__lassScriptLookup(...)} inside style block content.
|
|
514
|
+
*
|
|
515
|
+
* Story 5.1: Inside @{ } style blocks, $param should use the same helper as
|
|
516
|
+
* CSS zone to properly handle:
|
|
517
|
+
* - null -> 'unset' (CSS-meaningful fallback)
|
|
518
|
+
* - undefined or ReferenceError -> preserve '$name' unchanged
|
|
519
|
+
* - other values -> String coercion
|
|
520
|
+
*
|
|
521
|
+
* Reuses Scanner.findDollarVariablesStatic() for detection, which handles:
|
|
522
|
+
* - Protected contexts (strings, block comments)
|
|
523
|
+
* - {{ }} script block depth tracking
|
|
524
|
+
*
|
|
525
|
+
* @param text - Content inside a style block
|
|
526
|
+
* @returns Result with text and flag for $param usage
|
|
527
|
+
*/
|
|
528
|
+
function translateDollarVariablesInStyleBlock(text) {
|
|
529
|
+
// Reuse Scanner's detection logic - it handles all protected contexts and {{ }}
|
|
530
|
+
const variables = Scanner.findDollarVariablesStatic(text);
|
|
531
|
+
if (variables.length === 0) {
|
|
532
|
+
return { text, hasDollarVariables: false };
|
|
533
|
+
}
|
|
534
|
+
// Process from end to start so indices remain valid
|
|
535
|
+
let result = text;
|
|
536
|
+
for (let i = variables.length - 1; i >= 0; i--) {
|
|
537
|
+
const variable = variables[i];
|
|
538
|
+
const { varName, startIndex, endIndex } = variable;
|
|
539
|
+
// Replace $varName with ${__lassScriptLookup('name', () => $varName)}
|
|
540
|
+
const nameWithoutDollar = varName.slice(1);
|
|
541
|
+
const replacement = `\${__lassScriptLookup('${nameWithoutDollar}', () => ${varName})}`;
|
|
542
|
+
result = result.slice(0, startIndex) + replacement + result.slice(endIndex);
|
|
543
|
+
}
|
|
544
|
+
return { text: result, hasDollarVariables: true };
|
|
545
|
+
}
|
|
546
|
+
// ============================================================================
|
|
547
|
+
// STEP 5b: EXPRESSION PROCESSING
|
|
548
|
+
// ============================================================================
|
|
549
|
+
/**
|
|
550
|
+
* Step 5b: Process expressions in CSS zone.
|
|
551
|
+
*
|
|
552
|
+
* Finds {{ expr }} expressions and converts them to template literal interpolations.
|
|
553
|
+
* Story 2.5: Expressions are processed EVERYWHERE in CSS zone (strings, url(), comments).
|
|
554
|
+
* Story 5.1: Also translates @{ } style blocks within expressions.
|
|
555
|
+
*
|
|
556
|
+
* @param cssZone - The CSS zone content
|
|
557
|
+
* @param hasDollarVariables - Whether $param variables were found in CSS zone
|
|
558
|
+
* @param options - Transpile options (filename for errors)
|
|
559
|
+
* @returns Processed template with body and expression flag
|
|
560
|
+
*/
|
|
561
|
+
export function processExpressions(cssZone, hasDollarVariables, options) {
|
|
562
|
+
const scanner = new Scanner(cssZone, { filename: options.filename });
|
|
563
|
+
const exprSplit = scanner.findExpressions(cssZone);
|
|
564
|
+
const hasExpressions = exprSplit.parts.length > 1;
|
|
565
|
+
let styleBlockHasDollarVars = false;
|
|
566
|
+
// Build template literal content with ${} interpolations
|
|
567
|
+
let templateBody = '';
|
|
568
|
+
let exprIndex = 0;
|
|
569
|
+
for (let i = 0; i < exprSplit.parts.length; i++) {
|
|
570
|
+
if (i % 2 === 0) {
|
|
571
|
+
// CSS chunk - escape for template literal
|
|
572
|
+
templateBody += escapeForTemplateLiteral(exprSplit.parts[i]);
|
|
573
|
+
}
|
|
574
|
+
else {
|
|
575
|
+
// JS expression - translate @{ } style blocks, then wrap in helper
|
|
576
|
+
// Use V1 (recursive) which properly normalizes entire style block content
|
|
577
|
+
const exprContent = exprSplit.parts[i];
|
|
578
|
+
const hasStyleBlock = exprContent.includes('@{');
|
|
579
|
+
const styleBlockResult = translateStyleBlocks(exprContent);
|
|
580
|
+
if (styleBlockResult.hasDollarVariables) {
|
|
581
|
+
styleBlockHasDollarVars = true;
|
|
582
|
+
}
|
|
583
|
+
// Only pass indent for expressions containing style blocks
|
|
584
|
+
// Plain JS expressions (like .join('\n...')) should not be re-indented
|
|
585
|
+
if (hasStyleBlock) {
|
|
586
|
+
const exprPos = exprSplit.expressionPositions[exprIndex];
|
|
587
|
+
const indent = getIndentAtPosition(cssZone, exprPos);
|
|
588
|
+
if (indent) {
|
|
589
|
+
templateBody += '${__lassScriptExpression(' + styleBlockResult.text + ', "' + indent + '")}';
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
templateBody += '${__lassScriptExpression(' + styleBlockResult.text + ')}';
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
else {
|
|
596
|
+
templateBody += '${__lassScriptExpression(' + styleBlockResult.text + ')}';
|
|
597
|
+
}
|
|
598
|
+
exprIndex++;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
// Include $param usage from both CSS zone and style blocks
|
|
602
|
+
const finalHasDollarVariables = hasDollarVariables || styleBlockHasDollarVars;
|
|
603
|
+
return { templateBody, hasExpressions, hasDollarVariables: finalHasDollarVariables };
|
|
604
|
+
}
|
|
605
|
+
// ============================================================================
|
|
606
|
+
// STEP 6: OUTPUT BUILDING
|
|
607
|
+
// ============================================================================
|
|
608
|
+
/**
|
|
609
|
+
* Step 6: Build final JavaScript module output.
|
|
610
|
+
*
|
|
611
|
+
* Assembles preamble, helper functions (if needed), and template literal export.
|
|
612
|
+
* Story 5.1: Also translates @{ } style blocks in preamble.
|
|
613
|
+
*
|
|
614
|
+
* @param zones - Detected zones from step 1
|
|
615
|
+
* @param template - Processed template from step 5
|
|
616
|
+
* @returns Final JavaScript module code
|
|
617
|
+
*/
|
|
618
|
+
export function buildOutput(zones, template) {
|
|
619
|
+
// Translate @{ } style blocks in preamble (Story 5.1)
|
|
620
|
+
// Use V1 (recursive) which properly normalizes entire style block content
|
|
621
|
+
let preambleHasDollarVars = false;
|
|
622
|
+
let translatedPreamble = zones.preamble;
|
|
623
|
+
if (zones.hasSeparator && zones.preamble.trim()) {
|
|
624
|
+
const preambleResult = translateStyleBlocks(zones.preamble);
|
|
625
|
+
translatedPreamble = preambleResult.text;
|
|
626
|
+
preambleHasDollarVars = preambleResult.hasDollarVariables;
|
|
627
|
+
}
|
|
628
|
+
// Include helper functions as needed
|
|
629
|
+
let helpers = '';
|
|
630
|
+
if (template.hasExpressions) {
|
|
631
|
+
helpers += LASS_SCRIPT_EXPRESSION_HELPER + '\n';
|
|
632
|
+
}
|
|
633
|
+
if (template.hasDollarVariables || preambleHasDollarVars) {
|
|
634
|
+
helpers += LASS_SCRIPT_LOOKUP_HELPER + '\n';
|
|
635
|
+
}
|
|
636
|
+
if (helpers) {
|
|
637
|
+
helpers += '\n'; // Extra blank line after helpers
|
|
638
|
+
}
|
|
639
|
+
// Include preamble if present (non-empty after trimming)
|
|
640
|
+
if (zones.hasSeparator && zones.preamble.trim()) {
|
|
641
|
+
// Helpers (if needed) + Preamble + blank line + export
|
|
642
|
+
// Preamble executes when module is imported, variables are in scope
|
|
643
|
+
return `${helpers}${translatedPreamble}\n\nexport default \`${template.templateBody}\`;`;
|
|
644
|
+
}
|
|
645
|
+
else {
|
|
646
|
+
// No separator or empty/whitespace-only preamble - just export (with helpers if needed)
|
|
647
|
+
return `${helpers}export default \`${template.templateBody}\`;`;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
//# sourceMappingURL=transpiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transpiler.js","sourceRoot":"","sources":["../src/transpiler.ts"],"names":[],"mappings":"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"}
|