cf-pagetree-parser 1.0.0 → 1.0.3

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.
@@ -30,11 +30,12 @@ function sanitizeHtml(html) {
30
30
  * ============================================================================
31
31
  */
32
32
 
33
- // Use DOMPurify in browser, simple passthrough on server
34
- // Server-side parsing is from trusted FunnelWind source
35
- let DOMPurify = null;
36
- if (typeof window !== 'undefined') {
37
- import('dompurify').then(mod => { DOMPurify = mod.default; });
33
+ /**
34
+ * Sanitize HTML - passthrough for trusted FunnelWind source content
35
+ */
36
+ function sanitizeHtml(html) {
37
+ if (!html) return '';
38
+ return html;
38
39
  }
39
40
 
40
41
  /**
@@ -280,7 +281,7 @@ function extractTextContent(element) {
280
281
  /**
281
282
  * Parse HTML content to ContentEditableNode children
282
283
  * @param {string} html - The HTML content to parse
283
- * @param {string|null} defaultLinkColor - Default color for links (from styleguide or data attribute)
284
+ * @param {string|null} defaultLinkColor - Default color for links (from data attribute)
284
285
  */
285
286
  function parseHtmlToTextNodes(html, defaultLinkColor = null) {
286
287
  const temp = document.createElement('div');
@@ -922,7 +923,6 @@ function parseSectionContainer(element, parentId, index, parseChildren) {
922
923
  marginTop: spacing.marginTop || parseValueWithUnit('0px'),
923
924
  };
924
925
  const overlay = element.getAttribute('data-overlay');
925
- const paintColors = element.getAttribute('data-paint-colors');
926
926
 
927
927
  // Video background attributes
928
928
  const videoBgUrl = element.getAttribute('data-video-bg-url');
@@ -966,11 +966,6 @@ function parseSectionContainer(element, parentId, index, parseChildren) {
966
966
  node.attrs.id = elementId;
967
967
  }
968
968
 
969
- // Add paint colors if present
970
- if (paintColors) {
971
- node.attrs['data-paint-colors'] = paintColors;
972
- }
973
-
974
969
  // Apply spacing
975
970
  const { attrs: spacingAttrs, params: spacingParams } = spacingToAttrsAndParams(rowSpacingWithDefaults);
976
971
  Object.assign(node.attrs.style, spacingAttrs.style);
@@ -1099,7 +1094,6 @@ function parseRowContainer(element, parentId, index, parseChildren) {
1099
1094
  marginTop: spacing.marginTop || parseValueWithUnit('0px'),
1100
1095
  };
1101
1096
  const overlay = element.getAttribute('data-overlay');
1102
- const paintColors = element.getAttribute('data-paint-colors');
1103
1097
 
1104
1098
  const width = parseValueWithUnit(styles.width || '1170px');
1105
1099
 
@@ -1154,11 +1148,6 @@ function parseRowContainer(element, parentId, index, parseChildren) {
1154
1148
  node.attrs.id = elementId;
1155
1149
  }
1156
1150
 
1157
- // Add paint colors if present
1158
- if (paintColors) {
1159
- node.attrs['data-paint-colors'] = paintColors;
1160
- }
1161
-
1162
1151
  // Add className if set
1163
1152
  if (className) {
1164
1153
  node.attrs.className = className;
@@ -1302,7 +1291,6 @@ function parseColContainer(element, parentId, index, parseChildren) {
1302
1291
  const overlay = colInner.getAttribute('data-overlay');
1303
1292
  const separateCorners = colInner.getAttribute('data-separate-corners') === 'true';
1304
1293
  const borderRadius = parseBorderRadius(innerStyles);
1305
- const paintColors = colInner.getAttribute('data-paint-colors');
1306
1294
 
1307
1295
  const colInnerSelector = node.selectors['& > .col-inner'];
1308
1296
 
@@ -1418,11 +1406,6 @@ function parseColContainer(element, parentId, index, parseChildren) {
1418
1406
  colInnerSelector.attrs['data-skip-background-settings'] =
1419
1407
  (hasBackground || overlay) ? 'false' : 'true';
1420
1408
 
1421
- // Add paint colors if present
1422
- if (paintColors) {
1423
- colInnerSelector.attrs['data-paint-colors'] = paintColors;
1424
- }
1425
-
1426
1409
  // Parse children from col-inner, skipping overlay and content wrapper
1427
1410
  let childIdx = 0;
1428
1411
  const parseColInnerChildren = (container) => {
@@ -1482,7 +1465,6 @@ function parseFlexContainer(element, parentId, index, parseChildren) {
1482
1465
  marginTop: spacing.marginTop || parseValueWithUnit('0px'),
1483
1466
  };
1484
1467
  const overlay = element.getAttribute('data-overlay');
1485
- const paintColors = element.getAttribute('data-paint-colors');
1486
1468
 
1487
1469
  const width = parseValueWithUnit(styles.width || '100%', '%');
1488
1470
  const height = styles.height ? parseValueWithUnit(styles.height, 'px') : null;
@@ -1524,11 +1506,6 @@ function parseFlexContainer(element, parentId, index, parseChildren) {
1524
1506
  node.attrs.id = elementId;
1525
1507
  }
1526
1508
 
1527
- // Add paint colors if present
1528
- if (paintColors) {
1529
- node.attrs['data-paint-colors'] = paintColors;
1530
- }
1531
-
1532
1509
  // Add width
1533
1510
  node.attrs.style.width = width.value;
1534
1511
  node.params['width--unit'] = width.unit;
@@ -1640,8 +1617,7 @@ function parseTextElement(
1640
1617
  parentId,
1641
1618
  index,
1642
1619
  type,
1643
- selector,
1644
- _styleGuideAttr
1620
+ selector
1645
1621
  ) {
1646
1622
  const id = generateId();
1647
1623
  const contentEditableId = generateId();
@@ -1730,14 +1706,6 @@ function parseTextElement(
1730
1706
  selectorStyle["font-family"] = fontFamily;
1731
1707
  }
1732
1708
 
1733
- // Determine the style-guide-override param name based on type
1734
- const styleGuideOverrideMap = {
1735
- "Headline/V1": "style-guide-override-headline",
1736
- "SubHeadline/V1": "style-guide-override-subheadline",
1737
- "Paragraph/V1": "style-guide-override-content",
1738
- };
1739
- const styleGuideOverrideParam = styleGuideOverrideMap[type];
1740
-
1741
1709
  // Parse animation attributes
1742
1710
  const { attrs: animationAttrs, params: animationParams } = parseAnimationAttrs(element);
1743
1711
 
@@ -1764,7 +1732,6 @@ function parseTextElement(
1764
1732
  style: selectorStyle,
1765
1733
  },
1766
1734
  params: {
1767
- [styleGuideOverrideParam]: true,
1768
1735
  "font-size--unit": fontSize ? fontSize.unit : "px",
1769
1736
  "line-height--unit": "%",
1770
1737
  "letter-spacing--unit": "rem",
@@ -1847,8 +1814,7 @@ function parseHeadline(element, parentId, index) {
1847
1814
  parentId,
1848
1815
  index,
1849
1816
  "Headline/V1",
1850
- ".elHeadline",
1851
- "data-style-guide-headline"
1817
+ ".elHeadline"
1852
1818
  );
1853
1819
  }
1854
1820
 
@@ -1861,8 +1827,7 @@ function parseSubHeadline(element, parentId, index) {
1861
1827
  parentId,
1862
1828
  index,
1863
1829
  "SubHeadline/V1",
1864
- ".elSubheadline",
1865
- "data-style-guide-subheadline"
1830
+ ".elSubheadline"
1866
1831
  );
1867
1832
  }
1868
1833
 
@@ -1875,8 +1840,7 @@ function parseParagraph(element, parentId, index) {
1875
1840
  parentId,
1876
1841
  index,
1877
1842
  "Paragraph/V1",
1878
- ".elParagraph",
1879
- "data-style-guide-content"
1843
+ ".elParagraph"
1880
1844
  );
1881
1845
  }
1882
1846
 
@@ -1898,9 +1862,8 @@ function parseParagraph(element, parentId, index) {
1898
1862
  * @param {HTMLElement} element - The button element
1899
1863
  * @param {string} parentId - Parent element ID
1900
1864
  * @param {number} index - Child index
1901
- * @param {Object} styleguideData - Optional styleguide data for looking up button styles
1902
1865
  */
1903
- function parseButton(element, parentId, index, styleguideData = null) {
1866
+ function parseButton(element, parentId, index) {
1904
1867
  const id = generateId();
1905
1868
  const mainTextId = generateId();
1906
1869
  const subTextId = generateId();
@@ -1917,15 +1880,6 @@ function parseButton(element, parentId, index, styleguideData = null) {
1917
1880
  const hideIds = element.getAttribute('data-hide-ids');
1918
1881
  const elButtonType = element.getAttribute('data-elbuttontype');
1919
1882
 
1920
- // Check for styleguide button
1921
- const styleGuideButton = element.getAttribute('data-style-guide-button');
1922
-
1923
- // Look up button style from styleguide if available
1924
- let styleguideButtonStyle = null;
1925
- if (styleGuideButton && styleguideData?.buttons) {
1926
- styleguideButtonStyle = styleguideData.buttons.find(btn => btn.id === styleGuideButton);
1927
- }
1928
-
1929
1883
  // Find the anchor element for fallback parsing
1930
1884
  const anchor = element.querySelector('a');
1931
1885
  const anchorStyles = anchor ? parseInlineStyle(anchor.getAttribute('style') || '') : {};
@@ -1934,21 +1888,16 @@ function parseButton(element, parentId, index, styleguideData = null) {
1934
1888
  const textSpan = anchor ? anchor.querySelector('span') : null;
1935
1889
  const textStyles = textSpan ? parseInlineStyle(textSpan.getAttribute('style') || '') : {};
1936
1890
 
1937
- // Read from styleguide button style first, then data attributes, then inline styles
1938
- // Styleguide button structure: { regular: { bg, color }, hover: { bg, color }, borderRadius, borderWidth, borderColor }
1891
+ // Read from data attributes first, then inline styles
1939
1892
  const bgAttr = element.getAttribute('data-bg');
1940
- const bgColor = styleguideButtonStyle?.regular?.bg
1941
- ? normalizeColor(styleguideButtonStyle.regular.bg)
1942
- : bgAttr
1943
- ? normalizeColor(bgAttr)
1944
- : (normalizeColor(anchorStyles['background-color']) || '#3b82f6');
1893
+ const bgColor = bgAttr
1894
+ ? normalizeColor(bgAttr)
1895
+ : (normalizeColor(anchorStyles['background-color']) || '#3b82f6');
1945
1896
 
1946
1897
  const textColorAttr = element.getAttribute('data-color');
1947
- const textColor = styleguideButtonStyle?.regular?.color
1948
- ? normalizeColor(styleguideButtonStyle.regular.color)
1949
- : textColorAttr
1950
- ? normalizeColor(textColorAttr)
1951
- : (normalizeColor(textStyles.color) || '#ffffff');
1898
+ const textColor = textColorAttr
1899
+ ? normalizeColor(textColorAttr)
1900
+ : (normalizeColor(textStyles.color) || '#ffffff');
1952
1901
 
1953
1902
  // Font styling - prefer data attributes
1954
1903
  const fontSizeAttr = element.getAttribute('data-size');
@@ -1962,40 +1911,26 @@ function parseButton(element, parentId, index, styleguideData = null) {
1962
1911
  const paddingHorizontal = pxAttr ? parseValueWithUnit(pxAttr) : parseValueWithUnit(anchorStyles['padding-right'] || '32px');
1963
1912
  const paddingVertical = pyAttr ? parseValueWithUnit(pyAttr) : parseValueWithUnit(anchorStyles['padding-top'] || '16px');
1964
1913
 
1965
- // Border and corners - styleguide first, then data attributes
1914
+ // Border and corners - data attributes first, then inline styles
1966
1915
  const roundedAttr = element.getAttribute('data-rounded');
1967
- const borderRadius = styleguideButtonStyle?.borderRadius != null
1968
- ? { value: styleguideButtonStyle.borderRadius, unit: 'px' }
1969
- : roundedAttr
1970
- ? parseValueWithUnit(roundedAttr)
1971
- : parseBorderRadius(anchorStyles);
1916
+ const borderRadius = roundedAttr
1917
+ ? parseValueWithUnit(roundedAttr)
1918
+ : parseBorderRadius(anchorStyles);
1972
1919
 
1973
1920
  const borderColorAttr = element.getAttribute('data-border-color');
1974
- const borderColor = styleguideButtonStyle?.borderColor
1975
- ? normalizeColor(styleguideButtonStyle.borderColor)
1976
- : borderColorAttr
1977
- ? normalizeColor(borderColorAttr)
1978
- : normalizeColor(anchorStyles['border-color']);
1921
+ const borderColor = borderColorAttr
1922
+ ? normalizeColor(borderColorAttr)
1923
+ : normalizeColor(anchorStyles['border-color']);
1979
1924
 
1980
1925
  const borderWidthAttr = element.getAttribute('data-border-width');
1981
- const borderWidth = styleguideButtonStyle?.borderWidth != null
1982
- ? { value: styleguideButtonStyle.borderWidth, unit: 'px' }
1983
- : borderWidthAttr
1984
- ? parseValueWithUnit(borderWidthAttr)
1985
- : parseValueWithUnit(anchorStyles['border-width'] || '0');
1926
+ const borderWidth = borderWidthAttr
1927
+ ? parseValueWithUnit(borderWidthAttr)
1928
+ : parseValueWithUnit(anchorStyles['border-width'] || '0');
1986
1929
 
1987
1930
  // Shadow
1988
1931
  const shadowAttr = element.getAttribute('data-shadow');
1989
1932
  const shadow = shadowAttr ? parseShadow(shadowAttr) : parseShadow(anchorStyles['box-shadow']);
1990
1933
 
1991
- // Hover state from styleguide
1992
- const hoverBgColor = styleguideButtonStyle?.hover?.bg
1993
- ? normalizeColor(styleguideButtonStyle.hover.bg)
1994
- : null;
1995
- const hoverTextColor = styleguideButtonStyle?.hover?.color
1996
- ? normalizeColor(styleguideButtonStyle.hover.color)
1997
- : null;
1998
-
1999
1934
  // Alignment
2000
1935
  const textAlign = element.getAttribute('data-align') || parseTextAlign(wrapperStyles['text-align']);
2001
1936
 
@@ -2029,7 +1964,6 @@ function parseButton(element, parentId, index, styleguideData = null) {
2029
1964
  const fullWidth = element.getAttribute('data-full-width') === 'true';
2030
1965
 
2031
1966
  // Build button selector - always include padding params
2032
- // When using styleguide button, also include data-style-guide-button attribute
2033
1967
  const buttonSelector = {
2034
1968
  attrs: {
2035
1969
  style: {},
@@ -2039,7 +1973,6 @@ function parseButton(element, parentId, index, styleguideData = null) {
2039
1973
  '--style-padding-horizontal--unit': paddingHorizontal ? paddingHorizontal.unit : 'px',
2040
1974
  '--style-padding-vertical': paddingVertical ? paddingVertical.value : 16,
2041
1975
  '--style-padding-vertical--unit': paddingVertical ? paddingVertical.unit : 'px',
2042
- 'style-guide-override-button': true,
2043
1976
  '--style-background-color': bgColor,
2044
1977
  '--style-border-color': borderColor || 'transparent',
2045
1978
  '--style-border-width': borderWidth ? borderWidth.value : 0,
@@ -2047,11 +1980,6 @@ function parseButton(element, parentId, index, styleguideData = null) {
2047
1980
  },
2048
1981
  };
2049
1982
 
2050
- // Add styleguide button reference if present
2051
- if (styleGuideButton) {
2052
- buttonSelector.attrs['data-style-guide-button'] = styleGuideButton;
2053
- }
2054
-
2055
1983
  // Parse animation attributes
2056
1984
  const { attrs: animationAttrs, params: animationParams } = parseAnimationAttrs(element);
2057
1985
 
@@ -2218,27 +2146,6 @@ function parseButton(element, parentId, index, styleguideData = null) {
2218
2146
  node.selectors['.elButton .elButtonSub'].attrs.style.color = subTextColor;
2219
2147
  }
2220
2148
 
2221
- // Add hover state selectors if available from styleguide
2222
- if (hoverBgColor) {
2223
- node.selectors['.elButton:hover'] = {
2224
- attrs: {
2225
- style: {},
2226
- },
2227
- params: {
2228
- '--style-background-color': hoverBgColor,
2229
- },
2230
- };
2231
- }
2232
- if (hoverTextColor) {
2233
- node.selectors['.elButton:hover .elButtonText'] = {
2234
- attrs: {
2235
- style: {
2236
- color: hoverTextColor,
2237
- },
2238
- },
2239
- };
2240
- }
2241
-
2242
2149
  return node;
2243
2150
  }
2244
2151
 
@@ -3394,7 +3301,6 @@ function parseBulletList(element, parentId, index) {
3394
3301
  selectors: {
3395
3302
  '.elBulletList': {
3396
3303
  attrs: {
3397
- 'data-style-guide-content': 'm',
3398
3304
  'data-skip-text-shadow-settings': 'true',
3399
3305
  style: {
3400
3306
  color: textColor,
@@ -4216,8 +4122,6 @@ function parseCheckoutPlaceholder(element, parentId, index) {
4216
4122
  fractionalIndex: generateFractionalIndex(index),
4217
4123
  attrs: {
4218
4124
  style: {
4219
- '--container-font-family': 'var(--style-guide-font-family-content)',
4220
- '--input-headline-font-family': 'var(--style-guide-font-family-subheadline)',
4221
4125
  '--multiple-payments-font-family': 'sans-serif',
4222
4126
  '--input-background-color': '#FFFFFF',
4223
4127
  },
@@ -4391,276 +4295,6 @@ function parseConfirmationPlaceholder(element, parentId, index) {
4391
4295
  * ============================================================================
4392
4296
  */
4393
4297
 
4394
- /**
4395
- * Get typescale sizes calculated from baseSize and scaleRatio.
4396
- * Matches StyleguideEditor.tsx and cf-elements.js getTypescale() for consistency.
4397
- * Returns element-specific scales because headlines, subheadlines, and paragraphs
4398
- * have different sizes at the same preset (e.g., "s" for headline = 20px, "s" for paragraph = 13px).
4399
- *
4400
- * @param {Object} typography - Typography settings with baseSize and scaleRatio
4401
- * @returns {Object|null} - Map of element types to their size preset maps
4402
- */
4403
- function getTypescale(typography) {
4404
- if (!typography) return null;
4405
-
4406
- const { baseSize = 16, scaleRatio = 1.25 } = typography;
4407
- const r = scaleRatio;
4408
- const b = baseSize;
4409
-
4410
- // Build the base scale points (negative = smaller, positive = larger)
4411
- const scale = {
4412
- n3: Math.round(b / Math.pow(r, 3)), // ~8
4413
- n2: Math.round(b / Math.pow(r, 2)), // ~10
4414
- n1: Math.round(b / r), // ~13
4415
- base: b, // 16
4416
- p1: Math.round(b * r), // ~20
4417
- p2: Math.round(b * Math.pow(r, 2)), // ~25
4418
- p3: Math.round(b * Math.pow(r, 3)), // ~31
4419
- p4: Math.round(b * Math.pow(r, 4)), // ~39
4420
- p5: Math.round(b * Math.pow(r, 5)), // ~49
4421
- p6: Math.round(b * Math.pow(r, 6)), // ~61
4422
- p7: Math.round(b * Math.pow(r, 7)), // ~76
4423
- p8: Math.round(b * Math.pow(r, 8)), // ~95
4424
- };
4425
-
4426
- // Return element-specific scales (each element type maps presets to different scale points)
4427
- return {
4428
- headline: {
4429
- "5xl": scale.p8,
4430
- "4xl": scale.p7,
4431
- "3xl": scale.p6,
4432
- "2xl": scale.p5,
4433
- xl: scale.p4,
4434
- l: scale.p3,
4435
- lg: scale.p3,
4436
- m: scale.p2,
4437
- md: scale.p2,
4438
- s: scale.p1,
4439
- sm: scale.p1,
4440
- xs: scale.base,
4441
- },
4442
- subheadline: {
4443
- "5xl": scale.p7,
4444
- "4xl": scale.p6,
4445
- "3xl": scale.p5,
4446
- "2xl": scale.p4,
4447
- xl: scale.p3,
4448
- l: scale.p2,
4449
- lg: scale.p2,
4450
- m: scale.p1,
4451
- md: scale.p1,
4452
- s: scale.base,
4453
- sm: scale.base,
4454
- xs: scale.n1,
4455
- },
4456
- paragraph: {
4457
- "5xl": scale.p6,
4458
- "4xl": scale.p5,
4459
- "3xl": scale.p4,
4460
- "2xl": scale.p3,
4461
- xl: scale.p2,
4462
- l: scale.p1,
4463
- lg: scale.p1,
4464
- m: scale.base,
4465
- md: scale.base,
4466
- s: scale.n1,
4467
- sm: scale.n1,
4468
- xs: scale.n2,
4469
- },
4470
- };
4471
- }
4472
-
4473
- /**
4474
- * Apply styleguide fonts and colors as data attributes before parsing.
4475
- * This ensures the parser captures styleguide-applied values.
4476
- *
4477
- * @param {Document|HTMLElement} root - The root element or document to process
4478
- * @param {Object} styleguideData - Optional styleguide data (will try to read from embedded JSON if not provided)
4479
- */
4480
- function applyStyleguideDataAttributes(root, styleguideData = null) {
4481
- // Try to get styleguide from embedded JSON if not provided
4482
- if (!styleguideData) {
4483
- const scriptEl = root.querySelector
4484
- ? root.querySelector("#cf-styleguide-data")
4485
- : root.getElementById
4486
- ? root.getElementById("cf-styleguide-data")
4487
- : null;
4488
- if (scriptEl) {
4489
- try {
4490
- styleguideData = JSON.parse(scriptEl.textContent);
4491
- } catch (e) {
4492
- console.warn("PageTree Parser: Failed to parse styleguide data:", e);
4493
- return;
4494
- }
4495
- }
4496
- }
4497
-
4498
- if (!styleguideData) return;
4499
-
4500
- const { typography, paintThemes, colors } = styleguideData;
4501
-
4502
- // Helper to get color hex by ID
4503
- const getColorHex = (colorId) => {
4504
- if (!colors) return "#000000";
4505
- const color = colors.find((c) => c.id === colorId);
4506
- return color ? color.hex : "#000000";
4507
- };
4508
-
4509
- // Apply typography fonts to elements without explicit fonts
4510
- if (typography) {
4511
- const { headlineFont, subheadlineFont, contentFont } = typography;
4512
-
4513
- if (headlineFont) {
4514
- root
4515
- .querySelectorAll('[data-type="Headline/V1"]:not([data-font])')
4516
- .forEach((el) => {
4517
- el.setAttribute("data-font", headlineFont);
4518
- });
4519
- }
4520
-
4521
- if (subheadlineFont) {
4522
- root
4523
- .querySelectorAll('[data-type="SubHeadline/V1"]:not([data-font])')
4524
- .forEach((el) => {
4525
- el.setAttribute("data-font", subheadlineFont);
4526
- });
4527
- }
4528
-
4529
- if (contentFont) {
4530
- root
4531
- .querySelectorAll('[data-type="Paragraph/V1"]:not([data-font])')
4532
- .forEach((el) => {
4533
- el.setAttribute("data-font", contentFont);
4534
- });
4535
- }
4536
- }
4537
-
4538
- // Helper to check if element's closest paint-themed ancestor is the given container
4539
- // This prevents applying colors to elements inside nested non-paint containers
4540
- const isDirectPaintDescendant = (el, paintContainer) => {
4541
- // Find the closest ancestor with data-paint-colors attribute
4542
- const closestPaint = el.closest("[data-paint-colors]");
4543
- // Element should only get colors if its closest paint ancestor is this container
4544
- return closestPaint === paintContainer;
4545
- };
4546
-
4547
- // Apply paint theme colors - OVERRIDE existing (paint themes take precedence)
4548
- // Only apply to elements that are direct descendants (no intervening non-paint containers)
4549
- if (paintThemes?.length) {
4550
- paintThemes.forEach((theme) => {
4551
- const containers = root.querySelectorAll(
4552
- `[data-paint-colors="${theme.id}"]`
4553
- );
4554
- containers.forEach((container) => {
4555
- const headlineColor = getColorHex(theme.headlineColorId);
4556
- const subheadlineColor = getColorHex(theme.subheadlineColorId);
4557
- const contentColor = getColorHex(theme.contentColorId);
4558
- const iconColor = getColorHex(theme.iconColorId);
4559
- const linkColor = theme.linkColorId
4560
- ? getColorHex(theme.linkColorId)
4561
- : null;
4562
-
4563
- // Apply headline color (only to direct paint descendants)
4564
- container
4565
- .querySelectorAll('[data-type="Headline/V1"]')
4566
- .forEach((el) => {
4567
- if (isDirectPaintDescendant(el, container)) {
4568
- if (!el.hasAttribute("data-color-explicit")) {
4569
- el.setAttribute("data-color", headlineColor);
4570
- }
4571
- if (linkColor) el.setAttribute("data-link-color", linkColor);
4572
- }
4573
- });
4574
-
4575
- // Apply subheadline color (only to direct paint descendants)
4576
- container
4577
- .querySelectorAll('[data-type="SubHeadline/V1"]')
4578
- .forEach((el) => {
4579
- if (isDirectPaintDescendant(el, container)) {
4580
- if (!el.hasAttribute("data-color-explicit")) {
4581
- el.setAttribute("data-color", subheadlineColor);
4582
- }
4583
- if (linkColor) el.setAttribute("data-link-color", linkColor);
4584
- }
4585
- });
4586
-
4587
- // Apply content/paragraph color (only to direct paint descendants)
4588
- container
4589
- .querySelectorAll('[data-type="Paragraph/V1"]')
4590
- .forEach((el) => {
4591
- if (isDirectPaintDescendant(el, container)) {
4592
- if (!el.hasAttribute("data-color-explicit")) {
4593
- el.setAttribute("data-color", contentColor);
4594
- }
4595
- if (linkColor) el.setAttribute("data-link-color", linkColor);
4596
- }
4597
- });
4598
-
4599
- // Apply icon color (only to direct paint descendants)
4600
- container.querySelectorAll('[data-type="Icon/V1"]').forEach((el) => {
4601
- if (isDirectPaintDescendant(el, container)) {
4602
- if (!el.hasAttribute("data-color-explicit")) {
4603
- el.setAttribute("data-color", iconColor);
4604
- }
4605
- }
4606
- });
4607
-
4608
- // Apply colors to bullet lists (only to direct paint descendants)
4609
- container
4610
- .querySelectorAll('[data-type="BulletList/V1"]')
4611
- .forEach((el) => {
4612
- if (isDirectPaintDescendant(el, container)) {
4613
- if (!el.hasAttribute("data-text-color-explicit")) {
4614
- el.setAttribute("data-text-color", contentColor);
4615
- }
4616
- if (!el.hasAttribute("data-icon-color-explicit")) {
4617
- el.setAttribute("data-icon-color", iconColor);
4618
- }
4619
- if (linkColor) el.setAttribute("data-link-color", linkColor);
4620
- }
4621
- });
4622
- });
4623
- });
4624
- }
4625
-
4626
- // Resolve size presets (xl, l, m, s) to pixel values for text elements
4627
- // This allows the parser to capture correct font sizes even when using presets
4628
- if (typography) {
4629
- const typescale = getTypescale(typography);
4630
-
4631
- if (typescale) {
4632
- // Map data-type to element scale key
4633
- const elementTypeMap = {
4634
- "Headline/V1": "headline",
4635
- "SubHeadline/V1": "subheadline",
4636
- "Paragraph/V1": "paragraph",
4637
- "BulletList/V1": "paragraph", // Bullet lists use paragraph scale
4638
- };
4639
-
4640
- // Find all text elements with a size attribute
4641
- const textElements = root.querySelectorAll(
4642
- '[data-type="Headline/V1"][data-size], ' +
4643
- '[data-type="SubHeadline/V1"][data-size], ' +
4644
- '[data-type="Paragraph/V1"][data-size], ' +
4645
- '[data-type="BulletList/V1"][data-size]'
4646
- );
4647
-
4648
- textElements.forEach((el) => {
4649
- const sizeAttr = el.getAttribute("data-size");
4650
- const dataType = el.getAttribute("data-type");
4651
- const elementKey = elementTypeMap[dataType] || "headline";
4652
- const elementScale = typescale[elementKey];
4653
-
4654
- // Check if it's a preset (not already a px value)
4655
- if (sizeAttr && elementScale && elementScale[sizeAttr] !== undefined) {
4656
- // Set the resolved pixel value as a separate attribute
4657
- el.setAttribute("data-size-resolved", `${elementScale[sizeAttr]}px`);
4658
- }
4659
- });
4660
- }
4661
- }
4662
- }
4663
-
4664
4298
  /**
4665
4299
  * Map of data-type to parser function
4666
4300
  */
@@ -4696,10 +4330,10 @@ const PARSER_MAP = {
4696
4330
  };
4697
4331
 
4698
4332
  /**
4699
- * Create parseElement function with styleguide data in closure
4700
- * Also tracks element-id to internal-id mappings for scroll/show-hide resolution
4333
+ * Create parseElement function
4334
+ * Tracks element-id to internal-id mappings for scroll/show-hide resolution
4701
4335
  */
4702
- function createParseElement(styleguideData, elementIdMap) {
4336
+ function createParseElement(elementIdMap) {
4703
4337
  function parseElement(element, parentId, index) {
4704
4338
  const dataType = getDataType(element);
4705
4339
 
@@ -4726,9 +4360,6 @@ function createParseElement(styleguideData, elementIdMap) {
4726
4360
  let node;
4727
4361
  if (containerTypes.includes(dataType)) {
4728
4362
  node = parser(element, parentId, index, parseElement);
4729
- } else if (dataType === "Button/V1") {
4730
- // Button needs styleguide data to look up button styles
4731
- node = parser(element, parentId, index, styleguideData);
4732
4363
  } else {
4733
4364
  node = parser(element, parentId, index);
4734
4365
  }
@@ -4793,10 +4424,9 @@ function resolveButtonReferences(node, elementIdMap) {
4793
4424
  * Parse the entire page tree starting from a root element
4794
4425
  *
4795
4426
  * @param {HTMLElement} rootElement - The root element to parse (default: find ContentNode)
4796
- * @param {Object} styleguideData - Optional styleguide data for applying fonts/colors
4797
4427
  * @returns {Object} The pagetree JSON object
4798
4428
  */
4799
- function parsePageTree(rootElement = null, styleguideData = null) {
4429
+ function parsePageTree(rootElement = null) {
4800
4430
  // Find the root ContentNode if not provided
4801
4431
  if (!rootElement) {
4802
4432
  rootElement = document.querySelector('[data-type="ContentNode"]');
@@ -4807,16 +4437,14 @@ function parsePageTree(rootElement = null, styleguideData = null) {
4807
4437
  return null;
4808
4438
  }
4809
4439
 
4810
- // Apply styleguide fonts and colors as data attributes before parsing
4811
- // This ensures the parser captures styleguide-applied values (fonts, paint theme colors)
4440
+ // Get document root for popup detection
4812
4441
  const docRoot = rootElement.ownerDocument || document;
4813
- applyStyleguideDataAttributes(docRoot, styleguideData);
4814
4442
 
4815
4443
  // Create element ID map for scroll/show-hide reference resolution
4816
4444
  const elementIdMap = {};
4817
4445
 
4818
- // Create parseElement with styleguide data in closure for button style lookup
4819
- const parseElement = createParseElement(styleguideData, elementIdMap);
4446
+ // Create parseElement function
4447
+ const parseElement = createParseElement(elementIdMap);
4820
4448
 
4821
4449
  // Parse the content node
4822
4450
  const content = parseContentNode(rootElement, parseElement);
@@ -4935,7 +4563,6 @@ function parsePageTree(rootElement = null, styleguideData = null) {
4935
4563
  ".containerModal": {
4936
4564
  attrs: {
4937
4565
  "data-skip-corners-settings": "false",
4938
- "data-style-guide-corner": "style1",
4939
4566
  style: { "margin-bottom": 0 },
4940
4567
  },
4941
4568
  },
@@ -4951,15 +4578,10 @@ function parsePageTree(rootElement = null, styleguideData = null) {
4951
4578
  *
4952
4579
  * @param {HTMLElement} rootElement - The root element to parse
4953
4580
  * @param {boolean} pretty - Whether to pretty-print the JSON
4954
- * @param {Object} styleguideData - Optional styleguide data for applying fonts/colors
4955
4581
  * @returns {string} The pagetree as JSON string
4956
4582
  */
4957
- function exportPageTreeJSON(
4958
- rootElement = null,
4959
- pretty = true,
4960
- styleguideData = null
4961
- ) {
4962
- const pageTree = parsePageTree(rootElement, styleguideData);
4583
+ function exportPageTreeJSON(rootElement = null, pretty = true) {
4584
+ const pageTree = parsePageTree(rootElement);
4963
4585
  if (!pageTree) return null;
4964
4586
 
4965
4587
  return pretty ? JSON.stringify(pageTree, null, 2) : JSON.stringify(pageTree);
@@ -4970,14 +4592,9 @@ function exportPageTreeJSON(
4970
4592
  *
4971
4593
  * @param {string} filename - The filename (default: 'pagetree.json')
4972
4594
  * @param {HTMLElement} rootElement - The root element to parse
4973
- * @param {Object} styleguideData - Optional styleguide data for applying fonts/colors
4974
4595
  */
4975
- function downloadPageTree(
4976
- filename = "pagetree.json",
4977
- rootElement = null,
4978
- styleguideData = null
4979
- ) {
4980
- const json = exportPageTreeJSON(rootElement, true, styleguideData);
4596
+ function downloadPageTree(filename = "pagetree.json", rootElement = null) {
4597
+ const json = exportPageTreeJSON(rootElement, true);
4981
4598
  if (!json) return;
4982
4599
 
4983
4600
  const blob = new Blob([json], { type: "application/json" });
@@ -4996,14 +4613,10 @@ function downloadPageTree(
4996
4613
  * Copy pagetree JSON to clipboard
4997
4614
  *
4998
4615
  * @param {HTMLElement} rootElement - The root element to parse
4999
- * @param {Object} styleguideData - Optional styleguide data for applying fonts/colors
5000
4616
  * @returns {Promise<boolean>} Whether the copy was successful
5001
4617
  */
5002
- async function copyPageTreeToClipboard(
5003
- rootElement = null,
5004
- styleguideData = null
5005
- ) {
5006
- const json = exportPageTreeJSON(rootElement, true, styleguideData);
4618
+ async function copyPageTreeToClipboard(rootElement = null) {
4619
+ const json = exportPageTreeJSON(rootElement, true);
5007
4620
  if (!json) return false;
5008
4621
 
5009
4622
  try {
@@ -5021,10 +4634,9 @@ async function copyPageTreeToClipboard(
5021
4634
  // Expose API
5022
4635
  global.CFPageTreeParser = {
5023
4636
  parsePageTree,
5024
- parseElement,
5025
- extractPageSettings,
4637
+ createParseElement,
5026
4638
  exportPageTreeJSON,
5027
- downloadPageTreeJSON,
4639
+ downloadPageTree,
5028
4640
  copyPageTreeToClipboard,
5029
4641
  // Utils
5030
4642
  generateId,