cf-pagetree-parser 1.0.5 → 1.0.6

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/README.md CHANGED
@@ -13,14 +13,13 @@ npm install cf-pagetree-parser
13
13
  ### ES Modules (Next.js, Node.js)
14
14
 
15
15
  ```javascript
16
- import { parsePageTree, exportPageTreeJSON } from 'cf-pagetree-parser';
16
+ import { parsePageTree } from 'cf-pagetree-parser';
17
17
 
18
- // Parse a DOM element to PageTree
19
- const rootElement = document.querySelector('[data-type="ContentNode"]');
20
- const pageTree = parsePageTree(rootElement);
18
+ // Parse to PageTree JSON (automatically finds ContentNode)
19
+ const pageTree = parsePageTree();
21
20
 
22
- // Export as JSON string
23
- const json = exportPageTreeJSON(rootElement, true);
21
+ // The result is ready for ClickFunnels import
22
+ console.log(JSON.stringify(pageTree, null, 2));
24
23
  ```
25
24
 
26
25
  ### Browser (Standalone Bundle)
@@ -29,7 +28,9 @@ const json = exportPageTreeJSON(rootElement, true);
29
28
  <script src="dist/cf-pagetree-parser.js"></script>
30
29
  <script>
31
30
  const { parsePageTree } = CFPageTreeParser;
32
- const pageTree = parsePageTree(rootElement);
31
+
32
+ // Automatically finds ContentNode in the document
33
+ const pageTree = parsePageTree();
33
34
  </script>
34
35
  ```
35
36
 
@@ -41,12 +42,10 @@ The `dist/cf-pagetree-parser.js` bundle can be used in sandboxed extension conte
41
42
 
42
43
  ### Main Functions
43
44
 
44
- - `parsePageTree(rootElement)` - Parse DOM to PageTree object
45
- - `parseElement(element, parentId, index)` - Parse single element
46
- - `extractPageSettings(rootElement)` - Extract page settings
47
- - `exportPageTreeJSON(rootElement, formatted?)` - Export as JSON string
48
- - `downloadPageTreeJSON(rootElement, filename?)` - Download JSON file
49
- - `copyPageTreeToClipboard(rootElement)` - Copy to clipboard
45
+ - `parsePageTree(rootElement?)` - Parse DOM to PageTree object. If no element provided, automatically finds ContentNode.
46
+ - `exportPageTreeJSON(rootElement?, formatted?)` - Export as JSON string
47
+ - `downloadPageTree(filename?, rootElement?)` - Download JSON file
48
+ - `copyPageTreeToClipboard(rootElement?)` - Copy to clipboard
50
49
 
51
50
  ### Utilities
52
51
 
@@ -72,8 +71,8 @@ The parser extracts page-level settings from cf-page attributes:
72
71
  | Attribute | Description |
73
72
  |-----------|-------------|
74
73
  | `font` | Page font family (e.g., "Poppins"). Applied to body-level styles. |
75
- | `font-family` | Alias for `font` |
76
- | `text-color` | Default text color (default: #334155) |
74
+ | `color` | Default text color for all elements (default: #334155) |
75
+ | `text-color` | Alias for `color` |
77
76
  | `link-color` | Default link color (default: #3b82f6) |
78
77
  | `font-weight` | Default font weight |
79
78
  | `css` | Custom CSS (URL-encoded) |
@@ -1653,10 +1653,19 @@ function parseTextElement(
1653
1653
  ? parseFontFamily(fontAttr)
1654
1654
  : parseFontFamily(textStyles["font-family"]);
1655
1655
 
1656
+ // Get color: element data-color > inline style > page color > default
1656
1657
  const colorAttr = element.getAttribute("data-color");
1657
- const color = colorAttr
1658
- ? normalizeColor(colorAttr)
1659
- : normalizeColor(textStyles.color || "#000000");
1658
+ let color;
1659
+ if (colorAttr) {
1660
+ color = normalizeColor(colorAttr);
1661
+ } else if (textStyles.color) {
1662
+ color = normalizeColor(textStyles.color);
1663
+ } else {
1664
+ // Fall back to page-level color from ContentNode
1665
+ const contentNode = element.closest('[data-type="ContentNode"]');
1666
+ const pageColor = contentNode?.getAttribute("data-color") || contentNode?.getAttribute("data-text-color");
1667
+ color = pageColor ? normalizeColor(pageColor) : "#000000";
1668
+ }
1660
1669
 
1661
1670
  const alignAttr = element.getAttribute("data-align");
1662
1671
  const textAlign = alignAttr || parseTextAlign(textStyles["text-align"]);
@@ -3075,9 +3084,16 @@ function parseCheckbox(element, parentId, index) {
3075
3084
  const boxBorderColor = boxBorderMatch ? normalizeColor(boxBorderMatch[2]) : 'rgb(229, 231, 235)';
3076
3085
  const boxBorderRadius = parseBorderRadius(boxStyles);
3077
3086
 
3078
- // Label text styling
3087
+ // Label text styling - inherit page color if not set
3079
3088
  const textStyles = textSpan ? parseInlineStyle(textSpan.getAttribute('style') || '') : {};
3080
- const labelColor = normalizeColor(textStyles.color || '#334155');
3089
+ let labelColor;
3090
+ if (textStyles.color) {
3091
+ labelColor = normalizeColor(textStyles.color);
3092
+ } else {
3093
+ const contentNode = element.closest('[data-type="ContentNode"]');
3094
+ const pageColor = contentNode?.getAttribute("data-color") || contentNode?.getAttribute("data-text-color");
3095
+ labelColor = pageColor ? normalizeColor(pageColor) : '#334155';
3096
+ }
3081
3097
  const labelFontSize = parseValueWithUnit(textStyles['font-size'] || '16px');
3082
3098
 
3083
3099
  // Gap between checkbox and label
@@ -3229,12 +3245,17 @@ function parseBulletList(element, parentId, index) {
3229
3245
  // Find list items
3230
3246
  const items = ul ? ul.querySelectorAll('li') : [];
3231
3247
 
3248
+ // Get page-level color from ContentNode for fallback
3249
+ const contentNode = element.closest('[data-type="ContentNode"]');
3250
+ const pageColor = contentNode?.getAttribute("data-color") || contentNode?.getAttribute("data-text-color");
3251
+ const defaultTextColor = pageColor ? normalizeColor(pageColor) : '#334155';
3252
+
3232
3253
  // Initialize with defaults, will be overridden by data attrs or inline styles
3233
3254
  let iconClass = 'fas fa-check fa_icon';
3234
3255
  let iconColor = '#10b981';
3235
3256
  let iconMarginRight = 12;
3236
3257
  let iconSize = null;
3237
- let textColor = '#334155';
3258
+ let textColor = defaultTextColor;
3238
3259
  let textSize = null;
3239
3260
  let justifyContent = 'flex-start';
3240
3261
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cf-pagetree-parser",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Parse FunnelWind HTML to ClickFunnels PageTree JSON",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -562,9 +562,16 @@ export function parseCheckbox(element, parentId, index) {
562
562
  const boxBorderColor = boxBorderMatch ? normalizeColor(boxBorderMatch[2]) : 'rgb(229, 231, 235)';
563
563
  const boxBorderRadius = parseBorderRadius(boxStyles);
564
564
 
565
- // Label text styling
565
+ // Label text styling - inherit page color if not set
566
566
  const textStyles = textSpan ? parseInlineStyle(textSpan.getAttribute('style') || '') : {};
567
- const labelColor = normalizeColor(textStyles.color || '#334155');
567
+ let labelColor;
568
+ if (textStyles.color) {
569
+ labelColor = normalizeColor(textStyles.color);
570
+ } else {
571
+ const contentNode = element.closest('[data-type="ContentNode"]');
572
+ const pageColor = contentNode?.getAttribute("data-color") || contentNode?.getAttribute("data-text-color");
573
+ labelColor = pageColor ? normalizeColor(pageColor) : '#334155';
574
+ }
568
575
  const labelFontSize = parseValueWithUnit(textStyles['font-size'] || '16px');
569
576
 
570
577
  // Gap between checkbox and label
@@ -54,12 +54,17 @@ export function parseBulletList(element, parentId, index) {
54
54
  // Find list items
55
55
  const items = ul ? ul.querySelectorAll('li') : [];
56
56
 
57
+ // Get page-level color from ContentNode for fallback
58
+ const contentNode = element.closest('[data-type="ContentNode"]');
59
+ const pageColor = contentNode?.getAttribute("data-color") || contentNode?.getAttribute("data-text-color");
60
+ const defaultTextColor = pageColor ? normalizeColor(pageColor) : '#334155';
61
+
57
62
  // Initialize with defaults, will be overridden by data attrs or inline styles
58
63
  let iconClass = 'fas fa-check fa_icon';
59
64
  let iconColor = '#10b981';
60
65
  let iconMarginRight = 12;
61
66
  let iconSize = null;
62
- let textColor = '#334155';
67
+ let textColor = defaultTextColor;
63
68
  let textSize = null;
64
69
  let justifyContent = 'flex-start';
65
70
 
@@ -73,10 +73,19 @@ function parseTextElement(
73
73
  ? parseFontFamily(fontAttr)
74
74
  : parseFontFamily(textStyles["font-family"]);
75
75
 
76
+ // Get color: element data-color > inline style > page color > default
76
77
  const colorAttr = element.getAttribute("data-color");
77
- const color = colorAttr
78
- ? normalizeColor(colorAttr)
79
- : normalizeColor(textStyles.color || "#000000");
78
+ let color;
79
+ if (colorAttr) {
80
+ color = normalizeColor(colorAttr);
81
+ } else if (textStyles.color) {
82
+ color = normalizeColor(textStyles.color);
83
+ } else {
84
+ // Fall back to page-level color from ContentNode
85
+ const contentNode = element.closest('[data-type="ContentNode"]');
86
+ const pageColor = contentNode?.getAttribute("data-color") || contentNode?.getAttribute("data-text-color");
87
+ color = pageColor ? normalizeColor(pageColor) : "#000000";
88
+ }
80
89
 
81
90
  const alignAttr = element.getAttribute("data-align");
82
91
  const textAlign = alignAttr || parseTextAlign(textStyles["text-align"]);