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 +14 -15
- package/dist/cf-pagetree-parser.js +27 -6
- package/package.json +1 -1
- package/src/parsers/form.js +9 -2
- package/src/parsers/list.js +6 -1
- package/src/parsers/text.js +12 -3
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
|
|
16
|
+
import { parsePageTree } from 'cf-pagetree-parser';
|
|
17
17
|
|
|
18
|
-
// Parse
|
|
19
|
-
const
|
|
20
|
-
const pageTree = parsePageTree(rootElement);
|
|
18
|
+
// Parse to PageTree JSON (automatically finds ContentNode)
|
|
19
|
+
const pageTree = parsePageTree();
|
|
21
20
|
|
|
22
|
-
//
|
|
23
|
-
|
|
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
|
-
|
|
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
|
-
- `
|
|
46
|
-
- `
|
|
47
|
-
- `
|
|
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
|
-
| `
|
|
76
|
-
| `text-color` |
|
|
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
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
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
|
-
|
|
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 =
|
|
3258
|
+
let textColor = defaultTextColor;
|
|
3238
3259
|
let textSize = null;
|
|
3239
3260
|
let justifyContent = 'flex-start';
|
|
3240
3261
|
|
package/package.json
CHANGED
package/src/parsers/form.js
CHANGED
|
@@ -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
|
-
|
|
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
|
package/src/parsers/list.js
CHANGED
|
@@ -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 =
|
|
67
|
+
let textColor = defaultTextColor;
|
|
63
68
|
let textSize = null;
|
|
64
69
|
let justifyContent = 'flex-start';
|
|
65
70
|
|
package/src/parsers/text.js
CHANGED
|
@@ -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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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"]);
|