pulse-js-framework 1.7.20 → 1.7.22
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/compiler/parser.js +32 -13
- package/package.json +1 -1
package/compiler/parser.js
CHANGED
|
@@ -1575,17 +1575,24 @@ export class Parser {
|
|
|
1575
1575
|
const lastPart = selectorParts[selectorParts.length - 1];
|
|
1576
1576
|
|
|
1577
1577
|
// Don't add space after these (they attach to what follows)
|
|
1578
|
-
const noSpaceAfter = ['.', '#', ':', '[', '(', '>', '+', '~'];
|
|
1578
|
+
const noSpaceAfter = ['.', '#', ':', '[', '(', '>', '+', '~', '-'];
|
|
1579
1579
|
// Don't add space before these (they attach to what precedes)
|
|
1580
|
-
const noSpaceBefore = [':', ']', ')', ',', '.', '#'];
|
|
1580
|
+
const noSpaceBefore = [':', ']', ')', ',', '.', '#', '-'];
|
|
1581
1581
|
|
|
1582
1582
|
// Special case: . or # after an identifier needs space (descendant selector)
|
|
1583
1583
|
// e.g., ".school .date" - need space between "school" and "."
|
|
1584
1584
|
const isDescendantSelector = (tokenValue === '.' || tokenValue === '#') &&
|
|
1585
1585
|
lastToken?.type === TokenType.IDENT;
|
|
1586
1586
|
|
|
1587
|
+
// Special case: hyphenated class names like .job-title
|
|
1588
|
+
// Don't add space if current token is '-' and last token was IDENT
|
|
1589
|
+
// Or if last token was '-' (the next token should attach to it)
|
|
1590
|
+
const isHyphenatedIdent = (tokenValue === '-' && lastToken?.type === TokenType.IDENT) ||
|
|
1591
|
+
(lastToken?.type === TokenType.MINUS);
|
|
1592
|
+
|
|
1587
1593
|
const needsSpace = !noSpaceAfter.includes(lastPart) &&
|
|
1588
|
-
!noSpaceBefore.includes(tokenValue)
|
|
1594
|
+
!noSpaceBefore.includes(tokenValue) &&
|
|
1595
|
+
!isHyphenatedIdent ||
|
|
1589
1596
|
isDescendantSelector;
|
|
1590
1597
|
|
|
1591
1598
|
if (needsSpace) {
|
|
@@ -1682,13 +1689,14 @@ export class Parser {
|
|
|
1682
1689
|
|
|
1683
1690
|
// Tokens that should not have space after them in CSS values
|
|
1684
1691
|
const noSpaceAfter = new Set(['#', '(', '.', '/', 'rgba', 'rgb', 'hsl', 'hsla', 'var', 'calc', 'url', 'linear-gradient', 'radial-gradient']);
|
|
1685
|
-
// Tokens that should not have space before them
|
|
1686
|
-
const noSpaceBefore = new Set([')', ',', '%', 'px', 'em', 'rem', 'vh', 'vw', 'fr', 's', 'ms', '(']);
|
|
1692
|
+
// Tokens that should not have space before them (units and punctuation)
|
|
1693
|
+
const noSpaceBefore = new Set([')', ',', '%', 'px', 'em', 'rem', 'vh', 'vw', 'vmin', 'vmax', 'fr', 's', 'ms', '(', 'deg', 'rad', 'turn', 'grad', 'ex', 'ch', 'pt', 'pc', 'in', 'cm', 'mm']);
|
|
1687
1694
|
|
|
1688
1695
|
let value = '';
|
|
1689
1696
|
let lastTokenValue = '';
|
|
1690
1697
|
let lastTokenLine = this.current()?.line || 0;
|
|
1691
1698
|
let afterHash = false; // Track if we're collecting a hex color
|
|
1699
|
+
let hexColorLength = 0; // Track hex color length (max 8 for RRGGBBAA)
|
|
1692
1700
|
let inCssVar = false; // Track if we're inside var(--...)
|
|
1693
1701
|
|
|
1694
1702
|
while (!this.is(TokenType.SEMICOLON) && !this.is(TokenType.RBRACE) && !this.is(TokenType.EOF)) {
|
|
@@ -1713,12 +1721,24 @@ export class Parser {
|
|
|
1713
1721
|
}
|
|
1714
1722
|
|
|
1715
1723
|
// For hex colors (#abc123), collect tokens without spacing after #
|
|
1724
|
+
// Hex colors are 3, 4, 6, or 8 characters long
|
|
1716
1725
|
if (tokenValue === '#') {
|
|
1717
1726
|
afterHash = true;
|
|
1727
|
+
hexColorLength = 0;
|
|
1718
1728
|
} else if (afterHash) {
|
|
1719
|
-
//
|
|
1720
|
-
|
|
1721
|
-
|
|
1729
|
+
// Check if this token is a valid hex color continuation
|
|
1730
|
+
const tokenStr = String(tokenValue);
|
|
1731
|
+
const isHexChar = /^[0-9a-fA-F]+$/.test(tokenStr);
|
|
1732
|
+
if (isHexChar) {
|
|
1733
|
+
const newLength = hexColorLength + tokenStr.length;
|
|
1734
|
+
// Valid hex color lengths are 3, 4, 6, or 8
|
|
1735
|
+
// If adding this token would exceed a valid length, stop
|
|
1736
|
+
if (hexColorLength >= 6 || newLength > 8) {
|
|
1737
|
+
afterHash = false;
|
|
1738
|
+
} else {
|
|
1739
|
+
hexColorLength = newLength;
|
|
1740
|
+
}
|
|
1741
|
+
} else {
|
|
1722
1742
|
afterHash = false;
|
|
1723
1743
|
}
|
|
1724
1744
|
}
|
|
@@ -1727,16 +1747,15 @@ export class Parser {
|
|
|
1727
1747
|
// - It's the first token
|
|
1728
1748
|
// - Last token was in noSpaceAfter
|
|
1729
1749
|
// - This token is in noSpaceBefore
|
|
1730
|
-
// - We're collecting a hex color (afterHash
|
|
1750
|
+
// - We're collecting a hex color (afterHash is true)
|
|
1731
1751
|
// - We're inside var(--...) and this is part of the variable name
|
|
1732
1752
|
// - Last was '-' and current is an identifier (hyphenated name)
|
|
1733
|
-
const skipSpace = noSpaceAfter.has(lastTokenValue) ||
|
|
1753
|
+
const skipSpace = noSpaceAfter.has(String(lastTokenValue)) ||
|
|
1734
1754
|
noSpaceBefore.has(tokenValue) ||
|
|
1735
|
-
|
|
1736
|
-
(afterHash && /^[0-9a-fA-F]+$/.test(tokenValue)) ||
|
|
1755
|
+
afterHash ||
|
|
1737
1756
|
inCssVar ||
|
|
1738
1757
|
(lastTokenValue === '-' || lastTokenValue === '--') ||
|
|
1739
|
-
(tokenValue === '-' && /^[a-zA-Z]/.test(this.current()?.value || ''));
|
|
1758
|
+
(tokenValue === '-' && /^[a-zA-Z]/.test(String(this.current()?.value || '')));
|
|
1740
1759
|
|
|
1741
1760
|
if (value.length > 0 && !skipSpace) {
|
|
1742
1761
|
value += ' ';
|