@master/css-compiler 2.0.0-rc.70 → 2.0.0-rc.72
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/dist/core.mjs +137 -10
- package/dist/index.mjs +2 -1
- package/dist/lexer/standalone-master.mjs +3 -3
- package/package.json +1 -1
package/dist/core.mjs
CHANGED
|
@@ -367,10 +367,136 @@ function formatDeclarationValue(declaration) {
|
|
|
367
367
|
throw error;
|
|
368
368
|
}
|
|
369
369
|
const colonIndex = declarationText.indexOf(':');
|
|
370
|
-
return declarationText.slice(colonIndex + 1).trim();
|
|
370
|
+
return formatCSSNumberLiterals(declarationText.slice(colonIndex + 1).trim());
|
|
371
|
+
}
|
|
372
|
+
function normalizeNumberText(value) {
|
|
373
|
+
const [rawMantissa, rawExponent] = value.toLowerCase().replace('e+', 'e').split('e');
|
|
374
|
+
let mantissa = rawMantissa.replace(/^\+/, '');
|
|
375
|
+
if (mantissa.includes('.')) {
|
|
376
|
+
mantissa = mantissa.replace(/(\.\d*?)0+$/, '$1').replace(/\.$/, '');
|
|
377
|
+
}
|
|
378
|
+
if (mantissa === '-0') mantissa = '0';
|
|
379
|
+
mantissa = mantissa.replace(/^(-?)0\./, '$1.');
|
|
380
|
+
return rawExponent === undefined ? mantissa : `${mantissa}e${rawExponent}`;
|
|
371
381
|
}
|
|
372
382
|
function formatNumber(value) {
|
|
373
|
-
|
|
383
|
+
if (Object.is(value, -0)) return '0';
|
|
384
|
+
if (!Number.isFinite(value)) return String(value);
|
|
385
|
+
const direct = normalizeNumberText(String(value));
|
|
386
|
+
if (Number.isInteger(value)) return direct;
|
|
387
|
+
const target = Math.fround(value);
|
|
388
|
+
if (!Number.isFinite(target)) return direct;
|
|
389
|
+
let best = direct;
|
|
390
|
+
for(let precision = 1; precision <= 9; precision++){
|
|
391
|
+
const candidate = normalizeNumberText(target.toPrecision(precision));
|
|
392
|
+
if (!Object.is(Math.fround(Number(candidate)), target)) continue;
|
|
393
|
+
if (candidate.length < best.length || candidate.length === best.length && best.includes('e') && !candidate.includes('e')) {
|
|
394
|
+
best = candidate;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return best;
|
|
398
|
+
}
|
|
399
|
+
function isCSSIdentifierChar(value) {
|
|
400
|
+
return value !== undefined && /[-_a-zA-Z0-9]/.test(value);
|
|
401
|
+
}
|
|
402
|
+
function isCSSDigit(value) {
|
|
403
|
+
return value !== undefined && value >= '0' && value <= '9';
|
|
404
|
+
}
|
|
405
|
+
function canStartCSSNumber(value, index) {
|
|
406
|
+
const previous = value[index - 1];
|
|
407
|
+
if (isCSSIdentifierChar(previous) || previous === '#' || previous === '\\') return false;
|
|
408
|
+
const current = value[index];
|
|
409
|
+
const next = value[index + 1];
|
|
410
|
+
if (current === '+' || current === '-') {
|
|
411
|
+
return isCSSDigit(next) || next === '.' && isCSSDigit(value[index + 2]);
|
|
412
|
+
}
|
|
413
|
+
return isCSSDigit(current) || current === '.' && isCSSDigit(next);
|
|
414
|
+
}
|
|
415
|
+
function readCSSNumber(value, start) {
|
|
416
|
+
let index = start;
|
|
417
|
+
if (value[index] === '+' || value[index] === '-') index++;
|
|
418
|
+
let hasDigits = false;
|
|
419
|
+
while(isCSSDigit(value[index])){
|
|
420
|
+
hasDigits = true;
|
|
421
|
+
index++;
|
|
422
|
+
}
|
|
423
|
+
if (value[index] === '.') {
|
|
424
|
+
index++;
|
|
425
|
+
while(isCSSDigit(value[index])){
|
|
426
|
+
hasDigits = true;
|
|
427
|
+
index++;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
if (!hasDigits) return;
|
|
431
|
+
if (value[index] === 'e' || value[index] === 'E') {
|
|
432
|
+
let exponentIndex = index + 1;
|
|
433
|
+
if (value[exponentIndex] === '+' || value[exponentIndex] === '-') exponentIndex++;
|
|
434
|
+
const exponentStart = exponentIndex;
|
|
435
|
+
while(isCSSDigit(value[exponentIndex]))exponentIndex++;
|
|
436
|
+
if (exponentIndex > exponentStart) index = exponentIndex;
|
|
437
|
+
}
|
|
438
|
+
return {
|
|
439
|
+
text: value.slice(start, index),
|
|
440
|
+
end: index
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
function findCSSFunctionEnd(value, start) {
|
|
444
|
+
let depth = 0;
|
|
445
|
+
for(let index = start; index < value.length; index++){
|
|
446
|
+
const char = value[index];
|
|
447
|
+
if (char === '\\') {
|
|
448
|
+
index++;
|
|
449
|
+
continue;
|
|
450
|
+
}
|
|
451
|
+
if (char === '"' || char === '\'') {
|
|
452
|
+
index = findCSSClosingQuote(value, index, char);
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
if (char === '(') {
|
|
456
|
+
depth++;
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
if (char === ')') {
|
|
460
|
+
depth--;
|
|
461
|
+
if (depth === 0) return index + 1;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return value.length;
|
|
465
|
+
}
|
|
466
|
+
function formatCSSNumberLiterals(value) {
|
|
467
|
+
let result = '';
|
|
468
|
+
let index = 0;
|
|
469
|
+
while(index < value.length){
|
|
470
|
+
const char = value[index];
|
|
471
|
+
if (char === '\\') {
|
|
472
|
+
result += value.slice(index, index + 2);
|
|
473
|
+
index += 2;
|
|
474
|
+
continue;
|
|
475
|
+
}
|
|
476
|
+
if (char === '"' || char === '\'') {
|
|
477
|
+
const end = findCSSClosingQuote(value, index, char) + 1;
|
|
478
|
+
result += value.slice(index, end);
|
|
479
|
+
index = end;
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
if (value.slice(index, index + 4).toLowerCase() === 'url(' && !isCSSIdentifierChar(value[index - 1])) {
|
|
483
|
+
const end = findCSSFunctionEnd(value, index);
|
|
484
|
+
result += value.slice(index, end);
|
|
485
|
+
index = end;
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
488
|
+
if (canStartCSSNumber(value, index)) {
|
|
489
|
+
const number = readCSSNumber(value, index);
|
|
490
|
+
if (number) {
|
|
491
|
+
result += formatNumber(Number(number.text));
|
|
492
|
+
index = number.end;
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
result += char;
|
|
497
|
+
index++;
|
|
498
|
+
}
|
|
499
|
+
return result;
|
|
374
500
|
}
|
|
375
501
|
function formatDeclarationValueOverride(declaration) {
|
|
376
502
|
if (declaration.property !== 'aspect-ratio') return;
|
|
@@ -443,11 +569,11 @@ function formatToken(token) {
|
|
|
443
569
|
case 'unquoted-url':
|
|
444
570
|
return `url(${token.value})`;
|
|
445
571
|
case 'number':
|
|
446
|
-
return
|
|
572
|
+
return formatNumber(token.value);
|
|
447
573
|
case 'percentage':
|
|
448
|
-
return `${token.value * 100}%`;
|
|
574
|
+
return `${formatNumber(token.value * 100)}%`;
|
|
449
575
|
case 'dimension':
|
|
450
|
-
return `${token.value}${token.unit}`;
|
|
576
|
+
return `${formatNumber(token.value)}${token.unit}`;
|
|
451
577
|
case 'white-space':
|
|
452
578
|
return token.value;
|
|
453
579
|
case 'comment':
|
|
@@ -526,12 +652,13 @@ const COMPARISON_OPERATORS = {
|
|
|
526
652
|
};
|
|
527
653
|
function formatFeatureValue(value) {
|
|
528
654
|
if (value === undefined || value === null) return '';
|
|
529
|
-
if (typeof value === 'string'
|
|
655
|
+
if (typeof value === 'string') return value;
|
|
656
|
+
if (typeof value === 'number') return formatNumber(value);
|
|
530
657
|
switch(value.type){
|
|
531
658
|
case 'ident':
|
|
532
659
|
return value.value;
|
|
533
660
|
case 'number':
|
|
534
|
-
return
|
|
661
|
+
return formatNumber(value.value);
|
|
535
662
|
case 'length':
|
|
536
663
|
{
|
|
537
664
|
let resolvedValue = value.value;
|
|
@@ -544,7 +671,7 @@ function formatFeatureValue(value) {
|
|
|
544
671
|
case 'ratio':
|
|
545
672
|
return `${value.value.numerator}/${value.value.denominator}`;
|
|
546
673
|
default:
|
|
547
|
-
return formatPrelude(value) || String(value.value ?? '');
|
|
674
|
+
return formatPrelude(value) || (typeof value.value === 'number' ? formatNumber(value.value) : String(value.value ?? ''));
|
|
548
675
|
}
|
|
549
676
|
}
|
|
550
677
|
function formatCondition(condition) {
|
|
@@ -1316,9 +1443,9 @@ function formatKeyframeSelector(selector) {
|
|
|
1316
1443
|
case 'to':
|
|
1317
1444
|
return selector.type;
|
|
1318
1445
|
case 'percentage':
|
|
1319
|
-
return `${selector.value * 100}%`;
|
|
1446
|
+
return `${formatNumber(selector.value * 100)}%`;
|
|
1320
1447
|
case 'timeline-range-percentage':
|
|
1321
|
-
return `${selector.value.name} ${selector.value.percentage * 100}%`;
|
|
1448
|
+
return `${selector.value.name} ${formatNumber(selector.value.percentage * 100)}%`;
|
|
1322
1449
|
}
|
|
1323
1450
|
}
|
|
1324
1451
|
function parseKeyframes(rule, manifestInput, isStatic) {
|
package/dist/index.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { createRequire } from 'node:module';
|
|
|
3
3
|
import { isAbsolute, resolve, extname, dirname } from 'node:path';
|
|
4
4
|
import { transform } from 'lightningcss';
|
|
5
5
|
import { stringifyMasterCSSManifestJSON } from '@master/css-schema/manifest-json';
|
|
6
|
+
import { MASTER_CSS_ENTRY_DIRECTIVE_NAME } from '@master/css-lexer';
|
|
6
7
|
import { createMasterCSSManifest } from './master-css-manifest.mjs';
|
|
7
8
|
import lowerCSSDirectives from './lower-css-directives.mjs';
|
|
8
9
|
import { compileCSS, findCSSReferenceStatements, removeCSSReferenceStatements } from './core.mjs';
|
|
@@ -78,7 +79,7 @@ function resolveMasterCSSPackageEntryFile(importSource, fromFile = process.cwd()
|
|
|
78
79
|
return styleFile;
|
|
79
80
|
}
|
|
80
81
|
function inspectCSS(source) {
|
|
81
|
-
const hasMasterEntryDirective = findStandaloneMasterDirectiveStatements(source).some((statement)=>statement.name ===
|
|
82
|
+
const hasMasterEntryDirective = findStandaloneMasterDirectiveStatements(source).some((statement)=>statement.name === MASTER_CSS_ENTRY_DIRECTIVE_NAME);
|
|
82
83
|
const hasMasterCSSImport = findCSSImportStatements(source).some((statement)=>statement.source === MASTER_CSS_PACKAGE_ID);
|
|
83
84
|
return {
|
|
84
85
|
hasMasterEntryDirective,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { removeSourceRanges, escapeRegExp } from '@master/css-lexer';
|
|
1
|
+
import { removeSourceRanges, MASTER_CSS_ENTRY_DIRECTIVE_NAME, escapeRegExp } from '@master/css-lexer';
|
|
2
2
|
import { findAtRuleStatementEnd } from './source.mjs';
|
|
3
3
|
|
|
4
4
|
const STANDALONE_CSS_DIRECTIVE_NAMES = new Set([
|
|
@@ -131,8 +131,8 @@ function parseStandaloneCSSDirectiveStatement(source, start, atRuleName) {
|
|
|
131
131
|
if (end === -1) return;
|
|
132
132
|
const statement = source.slice(start, end);
|
|
133
133
|
const prelude = statement.replace(new RegExp(`^@${atRuleName}\\b`), '').replace(/;$/, '');
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
const name = atRuleName === 'master' ? MASTER_CSS_ENTRY_DIRECTIVE_NAME : atRuleName;
|
|
135
|
+
if (atRuleName === 'master' && prelude.trim() !== MASTER_CSS_ENTRY_DIRECTIVE_NAME) return;
|
|
136
136
|
return {
|
|
137
137
|
start,
|
|
138
138
|
end,
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@master/css-compiler","type":"module","scripts":{"build":"techor build \"src/**/*.ts\" --formats esm","dev":"pnpm build --watch","lint":"eslint","type-check":"tsc --noEmit","test":"vitest"},"license":"MIT","description":"Compile Master CSS stylesheet directives","author":"Aoyue Design LLC.","funding":"https://rc.css.master.co/sponsor","homepage":"https://css.master.co","bugs":{"url":"https://github.com/master-co/css/issues"},"repository":{"type":"git","url":"https://github.com/master-co/css.git","directory":"packages/compiler"},"keywords":["compiler","directives","css","mastercss"],"sideEffects":false,"main":"./dist/index.mjs","module":"./dist/index.mjs","jsnext:main":"./dist/index.mjs","esnext":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","default":"./dist/index.mjs"},"./browser":{"types":"./dist/browser.d.ts","import":"./dist/browser.mjs","default":"./dist/browser.mjs"}},"files":["dist"],"publishConfig":{"access":"public","provenance":true},"dependencies":{"@master/css-engine":"^2.0.0-rc.
|
|
1
|
+
{"name":"@master/css-compiler","type":"module","scripts":{"build":"techor build \"src/**/*.ts\" --formats esm","dev":"pnpm build --watch","lint":"eslint","type-check":"tsc --noEmit","test":"vitest"},"license":"MIT","description":"Compile Master CSS stylesheet directives","author":"Aoyue Design LLC.","funding":"https://rc.css.master.co/sponsor","homepage":"https://css.master.co","bugs":{"url":"https://github.com/master-co/css/issues"},"repository":{"type":"git","url":"https://github.com/master-co/css.git","directory":"packages/compiler"},"keywords":["compiler","directives","css","mastercss"],"sideEffects":false,"main":"./dist/index.mjs","module":"./dist/index.mjs","jsnext:main":"./dist/index.mjs","esnext":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","default":"./dist/index.mjs"},"./browser":{"types":"./dist/browser.d.ts","import":"./dist/browser.mjs","default":"./dist/browser.mjs"}},"files":["dist"],"publishConfig":{"access":"public","provenance":true},"dependencies":{"@master/css-engine":"^2.0.0-rc.72","@master/css-lexer":"^2.0.0-rc.72","css-tree":"^3.2.1","csstype":"^3.2.3","lightningcss":"^1.32.0","lightningcss-wasm":"^1.32.0","@master/css-schema":"^2.0.0-rc.72"},"devDependencies":{"@master/css-preset":"^2.0.0-rc.72","@types/css-tree":"^2.3.11"},"version":"2.0.0-rc.72"}
|