cf-pagetree-parser 1.0.7 → 1.0.9
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/dist/cf-pagetree-parser.js +92 -0
- package/package.json +2 -2
- package/src/index.js +2 -0
- package/src/parsers/layout.js +89 -0
- package/src/parsers/text.js +1 -0
|
@@ -958,6 +958,90 @@ function parseContentNode(element, parseChildren) {
|
|
|
958
958
|
return node;
|
|
959
959
|
}
|
|
960
960
|
|
|
961
|
+
/**
|
|
962
|
+
* Split rows whose columns' total span exceeds 12 into multiple rows.
|
|
963
|
+
* ClickFunnels renders all columns in a row side-by-side regardless of mdNum,
|
|
964
|
+
* so a row with e.g. 7 span-12 columns displays them all horizontally.
|
|
965
|
+
* This groups columns into batches that fit within 12 and creates separate rows.
|
|
966
|
+
*/
|
|
967
|
+
function splitOverflowingRows(rows, sectionId) {
|
|
968
|
+
const result = [];
|
|
969
|
+
|
|
970
|
+
for (const row of rows) {
|
|
971
|
+
if (row.type !== 'RowContainer/V1' || !row.children || row.children.length <= 1) {
|
|
972
|
+
result.push(row);
|
|
973
|
+
continue;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
const totalSpan = row.children.reduce((sum, col) => sum + (col.params?.mdNum || 12), 0);
|
|
977
|
+
if (totalSpan <= 12) {
|
|
978
|
+
result.push(row);
|
|
979
|
+
continue;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
// Group columns so each group's total span ≤ 12
|
|
983
|
+
const groups = [];
|
|
984
|
+
let currentGroup = [];
|
|
985
|
+
let currentSpan = 0;
|
|
986
|
+
|
|
987
|
+
for (const col of row.children) {
|
|
988
|
+
const colSpan = col.params?.mdNum || 12;
|
|
989
|
+
if (currentSpan + colSpan > 12 && currentGroup.length > 0) {
|
|
990
|
+
groups.push(currentGroup);
|
|
991
|
+
currentGroup = [];
|
|
992
|
+
currentSpan = 0;
|
|
993
|
+
}
|
|
994
|
+
currentGroup.push(col);
|
|
995
|
+
currentSpan += colSpan;
|
|
996
|
+
}
|
|
997
|
+
if (currentGroup.length > 0) {
|
|
998
|
+
groups.push(currentGroup);
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
// First group stays in the original row
|
|
1002
|
+
row.children = groups[0].map((col, idx) => {
|
|
1003
|
+
col.parentId = row.id;
|
|
1004
|
+
col.fractionalIndex = generateFractionalIndex(idx);
|
|
1005
|
+
return col;
|
|
1006
|
+
});
|
|
1007
|
+
result.push(row);
|
|
1008
|
+
|
|
1009
|
+
// Additional groups get new RowContainers with the same styling
|
|
1010
|
+
for (let g = 1; g < groups.length; g++) {
|
|
1011
|
+
const extraId = generateId();
|
|
1012
|
+
const extraRow = {
|
|
1013
|
+
type: row.type,
|
|
1014
|
+
id: extraId,
|
|
1015
|
+
version: 0,
|
|
1016
|
+
parentId: sectionId,
|
|
1017
|
+
fractionalIndex: '',
|
|
1018
|
+
attrs: JSON.parse(JSON.stringify(row.attrs)),
|
|
1019
|
+
params: JSON.parse(JSON.stringify(row.params)),
|
|
1020
|
+
selectors: JSON.parse(JSON.stringify(row.selectors)),
|
|
1021
|
+
children: groups[g].map((col, idx) => {
|
|
1022
|
+
col.parentId = extraId;
|
|
1023
|
+
col.fractionalIndex = generateFractionalIndex(idx);
|
|
1024
|
+
return col;
|
|
1025
|
+
}),
|
|
1026
|
+
};
|
|
1027
|
+
// Continuation rows should not duplicate the original row's margin-top
|
|
1028
|
+
if (extraRow.attrs.style) {
|
|
1029
|
+
extraRow.attrs.style['margin-top'] = 0;
|
|
1030
|
+
}
|
|
1031
|
+
// Remove any element-id to avoid duplicate IDs in the page
|
|
1032
|
+
delete extraRow.attrs.id;
|
|
1033
|
+
result.push(extraRow);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
// Re-index all rows with proper fractional indices
|
|
1038
|
+
result.forEach((row, idx) => {
|
|
1039
|
+
row.fractionalIndex = generateFractionalIndex(idx);
|
|
1040
|
+
});
|
|
1041
|
+
|
|
1042
|
+
return result;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
961
1045
|
/**
|
|
962
1046
|
* Parse SectionContainer
|
|
963
1047
|
*/
|
|
@@ -1126,6 +1210,11 @@ function parseSectionContainer(element, parentId, index, parseChildren) {
|
|
|
1126
1210
|
}
|
|
1127
1211
|
});
|
|
1128
1212
|
|
|
1213
|
+
// Split rows whose column spans exceed 12 into multiple rows.
|
|
1214
|
+
// ClickFunnels renders all columns in a row side-by-side, so a row with
|
|
1215
|
+
// e.g. 7 span-12 columns would display them all horizontally instead of stacking.
|
|
1216
|
+
node.children = splitOverflowingRows(node.children, id);
|
|
1217
|
+
|
|
1129
1218
|
return node;
|
|
1130
1219
|
}
|
|
1131
1220
|
|
|
@@ -1724,6 +1813,7 @@ function parseTextElement(
|
|
|
1724
1813
|
// Check cf-flex, cf-col, cf-row, cf-section in order (closest first)
|
|
1725
1814
|
const containerSelectors = [
|
|
1726
1815
|
'[data-type="FlexContainer/V1"]',
|
|
1816
|
+
'[data-type="FlexContainer/V2"]',
|
|
1727
1817
|
'[data-type="ColContainer/V1"]',
|
|
1728
1818
|
'[data-type="RowContainer/V1"]',
|
|
1729
1819
|
'[data-type="SectionContainer/V1"]',
|
|
@@ -4465,6 +4555,7 @@ const PARSER_MAP = {
|
|
|
4465
4555
|
"ColContainer/V1": parseColContainer,
|
|
4466
4556
|
"ColInner/V1": parseColInner,
|
|
4467
4557
|
"FlexContainer/V1": parseFlexContainer,
|
|
4558
|
+
"FlexContainer/V2": parseFlexContainer,
|
|
4468
4559
|
"Headline/V1": parseHeadline,
|
|
4469
4560
|
"SubHeadline/V1": parseSubHeadline,
|
|
4470
4561
|
"Paragraph/V1": parseParagraph,
|
|
@@ -4515,6 +4606,7 @@ function createParseElement(elementIdMap) {
|
|
|
4515
4606
|
"RowContainer/V1",
|
|
4516
4607
|
"ColContainer/V1",
|
|
4517
4608
|
"FlexContainer/V1",
|
|
4609
|
+
"FlexContainer/V2",
|
|
4518
4610
|
];
|
|
4519
4611
|
|
|
4520
4612
|
let node;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cf-pagetree-parser",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Parse FunnelWind HTML to ClickFunnels PageTree JSON",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -28,6 +28,6 @@
|
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"repository": {
|
|
30
30
|
"type": "git",
|
|
31
|
-
"url": "https://github.com/
|
|
31
|
+
"url": "https://github.com/PrimeMoverHQ/BarnumPT-Builder.git"
|
|
32
32
|
}
|
|
33
33
|
}
|
package/src/index.js
CHANGED
|
@@ -63,6 +63,7 @@ const PARSER_MAP = {
|
|
|
63
63
|
"ColContainer/V1": parseColContainer,
|
|
64
64
|
"ColInner/V1": parseColInner,
|
|
65
65
|
"FlexContainer/V1": parseFlexContainer,
|
|
66
|
+
"FlexContainer/V2": parseFlexContainer,
|
|
66
67
|
"Headline/V1": parseHeadline,
|
|
67
68
|
"SubHeadline/V1": parseSubHeadline,
|
|
68
69
|
"Paragraph/V1": parseParagraph,
|
|
@@ -113,6 +114,7 @@ function createParseElement(elementIdMap) {
|
|
|
113
114
|
"RowContainer/V1",
|
|
114
115
|
"ColContainer/V1",
|
|
115
116
|
"FlexContainer/V1",
|
|
117
|
+
"FlexContainer/V2",
|
|
116
118
|
];
|
|
117
119
|
|
|
118
120
|
let node;
|
package/src/parsers/layout.js
CHANGED
|
@@ -71,6 +71,90 @@ export function parseContentNode(element, parseChildren) {
|
|
|
71
71
|
return node;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Split rows whose columns' total span exceeds 12 into multiple rows.
|
|
76
|
+
* ClickFunnels renders all columns in a row side-by-side regardless of mdNum,
|
|
77
|
+
* so a row with e.g. 7 span-12 columns displays them all horizontally.
|
|
78
|
+
* This groups columns into batches that fit within 12 and creates separate rows.
|
|
79
|
+
*/
|
|
80
|
+
function splitOverflowingRows(rows, sectionId) {
|
|
81
|
+
const result = [];
|
|
82
|
+
|
|
83
|
+
for (const row of rows) {
|
|
84
|
+
if (row.type !== 'RowContainer/V1' || !row.children || row.children.length <= 1) {
|
|
85
|
+
result.push(row);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const totalSpan = row.children.reduce((sum, col) => sum + (col.params?.mdNum || 12), 0);
|
|
90
|
+
if (totalSpan <= 12) {
|
|
91
|
+
result.push(row);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Group columns so each group's total span ≤ 12
|
|
96
|
+
const groups = [];
|
|
97
|
+
let currentGroup = [];
|
|
98
|
+
let currentSpan = 0;
|
|
99
|
+
|
|
100
|
+
for (const col of row.children) {
|
|
101
|
+
const colSpan = col.params?.mdNum || 12;
|
|
102
|
+
if (currentSpan + colSpan > 12 && currentGroup.length > 0) {
|
|
103
|
+
groups.push(currentGroup);
|
|
104
|
+
currentGroup = [];
|
|
105
|
+
currentSpan = 0;
|
|
106
|
+
}
|
|
107
|
+
currentGroup.push(col);
|
|
108
|
+
currentSpan += colSpan;
|
|
109
|
+
}
|
|
110
|
+
if (currentGroup.length > 0) {
|
|
111
|
+
groups.push(currentGroup);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// First group stays in the original row
|
|
115
|
+
row.children = groups[0].map((col, idx) => {
|
|
116
|
+
col.parentId = row.id;
|
|
117
|
+
col.fractionalIndex = generateFractionalIndex(idx);
|
|
118
|
+
return col;
|
|
119
|
+
});
|
|
120
|
+
result.push(row);
|
|
121
|
+
|
|
122
|
+
// Additional groups get new RowContainers with the same styling
|
|
123
|
+
for (let g = 1; g < groups.length; g++) {
|
|
124
|
+
const extraId = generateId();
|
|
125
|
+
const extraRow = {
|
|
126
|
+
type: row.type,
|
|
127
|
+
id: extraId,
|
|
128
|
+
version: 0,
|
|
129
|
+
parentId: sectionId,
|
|
130
|
+
fractionalIndex: '',
|
|
131
|
+
attrs: JSON.parse(JSON.stringify(row.attrs)),
|
|
132
|
+
params: JSON.parse(JSON.stringify(row.params)),
|
|
133
|
+
selectors: JSON.parse(JSON.stringify(row.selectors)),
|
|
134
|
+
children: groups[g].map((col, idx) => {
|
|
135
|
+
col.parentId = extraId;
|
|
136
|
+
col.fractionalIndex = generateFractionalIndex(idx);
|
|
137
|
+
return col;
|
|
138
|
+
}),
|
|
139
|
+
};
|
|
140
|
+
// Continuation rows should not duplicate the original row's margin-top
|
|
141
|
+
if (extraRow.attrs.style) {
|
|
142
|
+
extraRow.attrs.style['margin-top'] = 0;
|
|
143
|
+
}
|
|
144
|
+
// Remove any element-id to avoid duplicate IDs in the page
|
|
145
|
+
delete extraRow.attrs.id;
|
|
146
|
+
result.push(extraRow);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Re-index all rows with proper fractional indices
|
|
151
|
+
result.forEach((row, idx) => {
|
|
152
|
+
row.fractionalIndex = generateFractionalIndex(idx);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
|
|
74
158
|
/**
|
|
75
159
|
* Parse SectionContainer
|
|
76
160
|
*/
|
|
@@ -239,6 +323,11 @@ export function parseSectionContainer(element, parentId, index, parseChildren) {
|
|
|
239
323
|
}
|
|
240
324
|
});
|
|
241
325
|
|
|
326
|
+
// Split rows whose column spans exceed 12 into multiple rows.
|
|
327
|
+
// ClickFunnels renders all columns in a row side-by-side, so a row with
|
|
328
|
+
// e.g. 7 span-12 columns would display them all horizontally instead of stacking.
|
|
329
|
+
node.children = splitOverflowingRows(node.children, id);
|
|
330
|
+
|
|
242
331
|
return node;
|
|
243
332
|
}
|
|
244
333
|
|
package/src/parsers/text.js
CHANGED
|
@@ -90,6 +90,7 @@ function parseTextElement(
|
|
|
90
90
|
// Check cf-flex, cf-col, cf-row, cf-section in order (closest first)
|
|
91
91
|
const containerSelectors = [
|
|
92
92
|
'[data-type="FlexContainer/V1"]',
|
|
93
|
+
'[data-type="FlexContainer/V2"]',
|
|
93
94
|
'[data-type="ColContainer/V1"]',
|
|
94
95
|
'[data-type="RowContainer/V1"]',
|
|
95
96
|
'[data-type="SectionContainer/V1"]',
|