cf-pagetree-parser 1.0.2 → 1.0.4
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 +17 -0
- package/dist/cf-pagetree-parser.js +14 -9
- package/package.json +1 -1
- package/src/index.js +2 -1
- package/src/parsers/text.js +4 -0
- package/src/utils.js +2 -16
package/README.md
CHANGED
|
@@ -65,6 +65,23 @@ The `dist/cf-pagetree-parser.js` bundle can be used in sandboxed extension conte
|
|
|
65
65
|
- `parseBackground(styles)` - Parse background styles
|
|
66
66
|
- `backgroundToParams(background)` - Convert background to CF params
|
|
67
67
|
|
|
68
|
+
## Page Settings
|
|
69
|
+
|
|
70
|
+
The parser extracts page-level settings from cf-page attributes:
|
|
71
|
+
|
|
72
|
+
| Attribute | Description |
|
|
73
|
+
|-----------|-------------|
|
|
74
|
+
| `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) |
|
|
77
|
+
| `link-color` | Default link color (default: #3b82f6) |
|
|
78
|
+
| `font-weight` | Default font weight |
|
|
79
|
+
| `css` | Custom CSS (URL-encoded) |
|
|
80
|
+
| `header-code` | Custom header HTML/scripts (URL-encoded) |
|
|
81
|
+
| `footer-code` | Custom footer HTML/scripts (URL-encoded) |
|
|
82
|
+
|
|
83
|
+
Font values are normalized to ClickFunnels format (e.g., `"Poppins", sans-serif`).
|
|
84
|
+
|
|
68
85
|
## Development
|
|
69
86
|
|
|
70
87
|
```bash
|
|
@@ -30,11 +30,12 @@ function sanitizeHtml(html) {
|
|
|
30
30
|
* ============================================================================
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
/**
|
|
@@ -1621,6 +1622,9 @@ function parseTextElement(
|
|
|
1621
1622
|
const id = generateId();
|
|
1622
1623
|
const contentEditableId = generateId();
|
|
1623
1624
|
|
|
1625
|
+
// Get element-id for scroll-to/show-hide targeting
|
|
1626
|
+
const elementId = element.getAttribute('id') || element.getAttribute('data-element-id');
|
|
1627
|
+
|
|
1624
1628
|
const wrapperStyles = parseInlineStyle(element.getAttribute("style") || "");
|
|
1625
1629
|
const spacing = parseSpacing(wrapperStyles);
|
|
1626
1630
|
|
|
@@ -1715,6 +1719,7 @@ function parseTextElement(
|
|
|
1715
1719
|
parentId,
|
|
1716
1720
|
fractionalIndex: generateFractionalIndex(index),
|
|
1717
1721
|
attrs: {
|
|
1722
|
+
...(elementId ? { id: elementId } : {}),
|
|
1718
1723
|
style: {},
|
|
1719
1724
|
...animationAttrs,
|
|
1720
1725
|
},
|
|
@@ -4466,7 +4471,8 @@ function parsePageTree(rootElement = null) {
|
|
|
4466
4471
|
const linkColorRaw = rootElement.getAttribute("data-link-color") || "#3b82f6";
|
|
4467
4472
|
const textColor = normalizeColor(textColorRaw);
|
|
4468
4473
|
const linkColor = normalizeColor(linkColorRaw);
|
|
4469
|
-
|
|
4474
|
+
// Support both 'font' (simple) and 'font-family' attributes
|
|
4475
|
+
const fontFamily = rootElement.getAttribute("data-font") || rootElement.getAttribute("data-font-family") || "";
|
|
4470
4476
|
const fontWeight = rootElement.getAttribute("data-font-weight") || "";
|
|
4471
4477
|
// Decode URL-encoded values
|
|
4472
4478
|
const headerCodeRaw = rootElement.getAttribute("data-header-code") || "";
|
|
@@ -4633,10 +4639,9 @@ async function copyPageTreeToClipboard(rootElement = null) {
|
|
|
4633
4639
|
// Expose API
|
|
4634
4640
|
global.CFPageTreeParser = {
|
|
4635
4641
|
parsePageTree,
|
|
4636
|
-
|
|
4637
|
-
extractPageSettings,
|
|
4642
|
+
createParseElement,
|
|
4638
4643
|
exportPageTreeJSON,
|
|
4639
|
-
|
|
4644
|
+
downloadPageTree,
|
|
4640
4645
|
copyPageTreeToClipboard,
|
|
4641
4646
|
// Utils
|
|
4642
4647
|
generateId,
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -225,7 +225,8 @@ export function parsePageTree(rootElement = null) {
|
|
|
225
225
|
const linkColorRaw = rootElement.getAttribute("data-link-color") || "#3b82f6";
|
|
226
226
|
const textColor = normalizeColor(textColorRaw);
|
|
227
227
|
const linkColor = normalizeColor(linkColorRaw);
|
|
228
|
-
|
|
228
|
+
// Support both 'font' (simple) and 'font-family' attributes
|
|
229
|
+
const fontFamily = rootElement.getAttribute("data-font") || rootElement.getAttribute("data-font-family") || "";
|
|
229
230
|
const fontWeight = rootElement.getAttribute("data-font-weight") || "";
|
|
230
231
|
// Decode URL-encoded values
|
|
231
232
|
const headerCodeRaw = rootElement.getAttribute("data-header-code") || "";
|
package/src/parsers/text.js
CHANGED
|
@@ -42,6 +42,9 @@ function parseTextElement(
|
|
|
42
42
|
const id = generateId();
|
|
43
43
|
const contentEditableId = generateId();
|
|
44
44
|
|
|
45
|
+
// Get element-id for scroll-to/show-hide targeting
|
|
46
|
+
const elementId = element.getAttribute('id') || element.getAttribute('data-element-id');
|
|
47
|
+
|
|
45
48
|
const wrapperStyles = parseInlineStyle(element.getAttribute("style") || "");
|
|
46
49
|
const spacing = parseSpacing(wrapperStyles);
|
|
47
50
|
|
|
@@ -136,6 +139,7 @@ function parseTextElement(
|
|
|
136
139
|
parentId,
|
|
137
140
|
fractionalIndex: generateFractionalIndex(index),
|
|
138
141
|
attrs: {
|
|
142
|
+
...(elementId ? { id: elementId } : {}),
|
|
139
143
|
style: {},
|
|
140
144
|
...animationAttrs,
|
|
141
145
|
},
|
package/src/utils.js
CHANGED
|
@@ -8,26 +8,12 @@
|
|
|
8
8
|
* ============================================================================
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
// Use DOMPurify in browser, simple passthrough on server
|
|
12
|
-
// Server-side parsing is from trusted FunnelWind source
|
|
13
|
-
let DOMPurify = null;
|
|
14
|
-
if (typeof window !== 'undefined') {
|
|
15
|
-
import('dompurify').then(mod => { DOMPurify = mod.default; });
|
|
16
|
-
}
|
|
17
|
-
|
|
18
11
|
/**
|
|
19
|
-
* Sanitize HTML
|
|
20
|
-
* Allows only safe formatting tags for text content
|
|
12
|
+
* Sanitize HTML - passthrough for trusted FunnelWind source content
|
|
21
13
|
*/
|
|
22
14
|
export function sanitizeHtml(html) {
|
|
23
15
|
if (!html) return '';
|
|
24
|
-
|
|
25
|
-
// (server-side parsing is from trusted FunnelWind source)
|
|
26
|
-
if (!DOMPurify) return html;
|
|
27
|
-
return DOMPurify.sanitize(html, {
|
|
28
|
-
ALLOWED_TAGS: ['b', 'strong', 'i', 'em', 'u', 's', 'strike', 'a', 'br', 'span', 'li'],
|
|
29
|
-
ALLOWED_ATTR: ['href', 'target', 'rel', 'style', 'class'],
|
|
30
|
-
});
|
|
16
|
+
return html;
|
|
31
17
|
}
|
|
32
18
|
|
|
33
19
|
/**
|