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.
Files changed (2) hide show
  1. package/compiler/parser.js +32 -13
  2. package/package.json +1 -1
@@ -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
- // Still collecting hex color - no space
1720
- // Stop collecting when we hit a space-requiring character
1721
- if (tokenValue === ' ' || tokenValue === ';' || tokenValue === ')') {
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 and last was #)
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
- (afterHash && lastTokenValue === '#') ||
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 += ' ';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pulse-js-framework",
3
- "version": "1.7.20",
3
+ "version": "1.7.22",
4
4
  "description": "A declarative DOM framework with CSS selector-based structure and reactive pulsations",
5
5
  "type": "module",
6
6
  "main": "index.js",