cf-pagetree-parser 1.0.0 → 1.0.2
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 +8 -8
- package/dist/cf-pagetree-parser.js +36 -424
- package/package.json +2 -2
- package/src/index.js +13 -304
- package/src/parsers/button.js +18 -75
- package/src/parsers/layout.js +0 -24
- package/src/parsers/list.js +0 -1
- package/src/parsers/placeholders.js +0 -2
- package/src/parsers/text.js +4 -17
- package/src/utils.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cf-pagetree-parser",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
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/WynterJones/cf-pagetree-parser"
|
|
32
32
|
}
|
|
33
33
|
}
|
package/src/index.js
CHANGED
|
@@ -53,276 +53,6 @@ import {
|
|
|
53
53
|
parseModalContainer,
|
|
54
54
|
} from "./parsers/index.js";
|
|
55
55
|
|
|
56
|
-
/**
|
|
57
|
-
* Get typescale sizes calculated from baseSize and scaleRatio.
|
|
58
|
-
* Matches StyleguideEditor.tsx and cf-elements.js getTypescale() for consistency.
|
|
59
|
-
* Returns element-specific scales because headlines, subheadlines, and paragraphs
|
|
60
|
-
* have different sizes at the same preset (e.g., "s" for headline = 20px, "s" for paragraph = 13px).
|
|
61
|
-
*
|
|
62
|
-
* @param {Object} typography - Typography settings with baseSize and scaleRatio
|
|
63
|
-
* @returns {Object|null} - Map of element types to their size preset maps
|
|
64
|
-
*/
|
|
65
|
-
function getTypescale(typography) {
|
|
66
|
-
if (!typography) return null;
|
|
67
|
-
|
|
68
|
-
const { baseSize = 16, scaleRatio = 1.25 } = typography;
|
|
69
|
-
const r = scaleRatio;
|
|
70
|
-
const b = baseSize;
|
|
71
|
-
|
|
72
|
-
// Build the base scale points (negative = smaller, positive = larger)
|
|
73
|
-
const scale = {
|
|
74
|
-
n3: Math.round(b / Math.pow(r, 3)), // ~8
|
|
75
|
-
n2: Math.round(b / Math.pow(r, 2)), // ~10
|
|
76
|
-
n1: Math.round(b / r), // ~13
|
|
77
|
-
base: b, // 16
|
|
78
|
-
p1: Math.round(b * r), // ~20
|
|
79
|
-
p2: Math.round(b * Math.pow(r, 2)), // ~25
|
|
80
|
-
p3: Math.round(b * Math.pow(r, 3)), // ~31
|
|
81
|
-
p4: Math.round(b * Math.pow(r, 4)), // ~39
|
|
82
|
-
p5: Math.round(b * Math.pow(r, 5)), // ~49
|
|
83
|
-
p6: Math.round(b * Math.pow(r, 6)), // ~61
|
|
84
|
-
p7: Math.round(b * Math.pow(r, 7)), // ~76
|
|
85
|
-
p8: Math.round(b * Math.pow(r, 8)), // ~95
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
// Return element-specific scales (each element type maps presets to different scale points)
|
|
89
|
-
return {
|
|
90
|
-
headline: {
|
|
91
|
-
"5xl": scale.p8,
|
|
92
|
-
"4xl": scale.p7,
|
|
93
|
-
"3xl": scale.p6,
|
|
94
|
-
"2xl": scale.p5,
|
|
95
|
-
xl: scale.p4,
|
|
96
|
-
l: scale.p3,
|
|
97
|
-
lg: scale.p3,
|
|
98
|
-
m: scale.p2,
|
|
99
|
-
md: scale.p2,
|
|
100
|
-
s: scale.p1,
|
|
101
|
-
sm: scale.p1,
|
|
102
|
-
xs: scale.base,
|
|
103
|
-
},
|
|
104
|
-
subheadline: {
|
|
105
|
-
"5xl": scale.p7,
|
|
106
|
-
"4xl": scale.p6,
|
|
107
|
-
"3xl": scale.p5,
|
|
108
|
-
"2xl": scale.p4,
|
|
109
|
-
xl: scale.p3,
|
|
110
|
-
l: scale.p2,
|
|
111
|
-
lg: scale.p2,
|
|
112
|
-
m: scale.p1,
|
|
113
|
-
md: scale.p1,
|
|
114
|
-
s: scale.base,
|
|
115
|
-
sm: scale.base,
|
|
116
|
-
xs: scale.n1,
|
|
117
|
-
},
|
|
118
|
-
paragraph: {
|
|
119
|
-
"5xl": scale.p6,
|
|
120
|
-
"4xl": scale.p5,
|
|
121
|
-
"3xl": scale.p4,
|
|
122
|
-
"2xl": scale.p3,
|
|
123
|
-
xl: scale.p2,
|
|
124
|
-
l: scale.p1,
|
|
125
|
-
lg: scale.p1,
|
|
126
|
-
m: scale.base,
|
|
127
|
-
md: scale.base,
|
|
128
|
-
s: scale.n1,
|
|
129
|
-
sm: scale.n1,
|
|
130
|
-
xs: scale.n2,
|
|
131
|
-
},
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Apply styleguide fonts and colors as data attributes before parsing.
|
|
137
|
-
* This ensures the parser captures styleguide-applied values.
|
|
138
|
-
*
|
|
139
|
-
* @param {Document|HTMLElement} root - The root element or document to process
|
|
140
|
-
* @param {Object} styleguideData - Optional styleguide data (will try to read from embedded JSON if not provided)
|
|
141
|
-
*/
|
|
142
|
-
function applyStyleguideDataAttributes(root, styleguideData = null) {
|
|
143
|
-
// Try to get styleguide from embedded JSON if not provided
|
|
144
|
-
if (!styleguideData) {
|
|
145
|
-
const scriptEl = root.querySelector
|
|
146
|
-
? root.querySelector("#cf-styleguide-data")
|
|
147
|
-
: root.getElementById
|
|
148
|
-
? root.getElementById("cf-styleguide-data")
|
|
149
|
-
: null;
|
|
150
|
-
if (scriptEl) {
|
|
151
|
-
try {
|
|
152
|
-
styleguideData = JSON.parse(scriptEl.textContent);
|
|
153
|
-
} catch (e) {
|
|
154
|
-
console.warn("PageTree Parser: Failed to parse styleguide data:", e);
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (!styleguideData) return;
|
|
161
|
-
|
|
162
|
-
const { typography, paintThemes, colors } = styleguideData;
|
|
163
|
-
|
|
164
|
-
// Helper to get color hex by ID
|
|
165
|
-
const getColorHex = (colorId) => {
|
|
166
|
-
if (!colors) return "#000000";
|
|
167
|
-
const color = colors.find((c) => c.id === colorId);
|
|
168
|
-
return color ? color.hex : "#000000";
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
// Apply typography fonts to elements without explicit fonts
|
|
172
|
-
if (typography) {
|
|
173
|
-
const { headlineFont, subheadlineFont, contentFont } = typography;
|
|
174
|
-
|
|
175
|
-
if (headlineFont) {
|
|
176
|
-
root
|
|
177
|
-
.querySelectorAll('[data-type="Headline/V1"]:not([data-font])')
|
|
178
|
-
.forEach((el) => {
|
|
179
|
-
el.setAttribute("data-font", headlineFont);
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
if (subheadlineFont) {
|
|
184
|
-
root
|
|
185
|
-
.querySelectorAll('[data-type="SubHeadline/V1"]:not([data-font])')
|
|
186
|
-
.forEach((el) => {
|
|
187
|
-
el.setAttribute("data-font", subheadlineFont);
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (contentFont) {
|
|
192
|
-
root
|
|
193
|
-
.querySelectorAll('[data-type="Paragraph/V1"]:not([data-font])')
|
|
194
|
-
.forEach((el) => {
|
|
195
|
-
el.setAttribute("data-font", contentFont);
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Helper to check if element's closest paint-themed ancestor is the given container
|
|
201
|
-
// This prevents applying colors to elements inside nested non-paint containers
|
|
202
|
-
const isDirectPaintDescendant = (el, paintContainer) => {
|
|
203
|
-
// Find the closest ancestor with data-paint-colors attribute
|
|
204
|
-
const closestPaint = el.closest("[data-paint-colors]");
|
|
205
|
-
// Element should only get colors if its closest paint ancestor is this container
|
|
206
|
-
return closestPaint === paintContainer;
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
// Apply paint theme colors - OVERRIDE existing (paint themes take precedence)
|
|
210
|
-
// Only apply to elements that are direct descendants (no intervening non-paint containers)
|
|
211
|
-
if (paintThemes?.length) {
|
|
212
|
-
paintThemes.forEach((theme) => {
|
|
213
|
-
const containers = root.querySelectorAll(
|
|
214
|
-
`[data-paint-colors="${theme.id}"]`
|
|
215
|
-
);
|
|
216
|
-
containers.forEach((container) => {
|
|
217
|
-
const headlineColor = getColorHex(theme.headlineColorId);
|
|
218
|
-
const subheadlineColor = getColorHex(theme.subheadlineColorId);
|
|
219
|
-
const contentColor = getColorHex(theme.contentColorId);
|
|
220
|
-
const iconColor = getColorHex(theme.iconColorId);
|
|
221
|
-
const linkColor = theme.linkColorId
|
|
222
|
-
? getColorHex(theme.linkColorId)
|
|
223
|
-
: null;
|
|
224
|
-
|
|
225
|
-
// Apply headline color (only to direct paint descendants)
|
|
226
|
-
container
|
|
227
|
-
.querySelectorAll('[data-type="Headline/V1"]')
|
|
228
|
-
.forEach((el) => {
|
|
229
|
-
if (isDirectPaintDescendant(el, container)) {
|
|
230
|
-
if (!el.hasAttribute("data-color-explicit")) {
|
|
231
|
-
el.setAttribute("data-color", headlineColor);
|
|
232
|
-
}
|
|
233
|
-
if (linkColor) el.setAttribute("data-link-color", linkColor);
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
// Apply subheadline color (only to direct paint descendants)
|
|
238
|
-
container
|
|
239
|
-
.querySelectorAll('[data-type="SubHeadline/V1"]')
|
|
240
|
-
.forEach((el) => {
|
|
241
|
-
if (isDirectPaintDescendant(el, container)) {
|
|
242
|
-
if (!el.hasAttribute("data-color-explicit")) {
|
|
243
|
-
el.setAttribute("data-color", subheadlineColor);
|
|
244
|
-
}
|
|
245
|
-
if (linkColor) el.setAttribute("data-link-color", linkColor);
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
// Apply content/paragraph color (only to direct paint descendants)
|
|
250
|
-
container
|
|
251
|
-
.querySelectorAll('[data-type="Paragraph/V1"]')
|
|
252
|
-
.forEach((el) => {
|
|
253
|
-
if (isDirectPaintDescendant(el, container)) {
|
|
254
|
-
if (!el.hasAttribute("data-color-explicit")) {
|
|
255
|
-
el.setAttribute("data-color", contentColor);
|
|
256
|
-
}
|
|
257
|
-
if (linkColor) el.setAttribute("data-link-color", linkColor);
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
// Apply icon color (only to direct paint descendants)
|
|
262
|
-
container.querySelectorAll('[data-type="Icon/V1"]').forEach((el) => {
|
|
263
|
-
if (isDirectPaintDescendant(el, container)) {
|
|
264
|
-
if (!el.hasAttribute("data-color-explicit")) {
|
|
265
|
-
el.setAttribute("data-color", iconColor);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
// Apply colors to bullet lists (only to direct paint descendants)
|
|
271
|
-
container
|
|
272
|
-
.querySelectorAll('[data-type="BulletList/V1"]')
|
|
273
|
-
.forEach((el) => {
|
|
274
|
-
if (isDirectPaintDescendant(el, container)) {
|
|
275
|
-
if (!el.hasAttribute("data-text-color-explicit")) {
|
|
276
|
-
el.setAttribute("data-text-color", contentColor);
|
|
277
|
-
}
|
|
278
|
-
if (!el.hasAttribute("data-icon-color-explicit")) {
|
|
279
|
-
el.setAttribute("data-icon-color", iconColor);
|
|
280
|
-
}
|
|
281
|
-
if (linkColor) el.setAttribute("data-link-color", linkColor);
|
|
282
|
-
}
|
|
283
|
-
});
|
|
284
|
-
});
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// Resolve size presets (xl, l, m, s) to pixel values for text elements
|
|
289
|
-
// This allows the parser to capture correct font sizes even when using presets
|
|
290
|
-
if (typography) {
|
|
291
|
-
const typescale = getTypescale(typography);
|
|
292
|
-
|
|
293
|
-
if (typescale) {
|
|
294
|
-
// Map data-type to element scale key
|
|
295
|
-
const elementTypeMap = {
|
|
296
|
-
"Headline/V1": "headline",
|
|
297
|
-
"SubHeadline/V1": "subheadline",
|
|
298
|
-
"Paragraph/V1": "paragraph",
|
|
299
|
-
"BulletList/V1": "paragraph", // Bullet lists use paragraph scale
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
// Find all text elements with a size attribute
|
|
303
|
-
const textElements = root.querySelectorAll(
|
|
304
|
-
'[data-type="Headline/V1"][data-size], ' +
|
|
305
|
-
'[data-type="SubHeadline/V1"][data-size], ' +
|
|
306
|
-
'[data-type="Paragraph/V1"][data-size], ' +
|
|
307
|
-
'[data-type="BulletList/V1"][data-size]'
|
|
308
|
-
);
|
|
309
|
-
|
|
310
|
-
textElements.forEach((el) => {
|
|
311
|
-
const sizeAttr = el.getAttribute("data-size");
|
|
312
|
-
const dataType = el.getAttribute("data-type");
|
|
313
|
-
const elementKey = elementTypeMap[dataType] || "headline";
|
|
314
|
-
const elementScale = typescale[elementKey];
|
|
315
|
-
|
|
316
|
-
// Check if it's a preset (not already a px value)
|
|
317
|
-
if (sizeAttr && elementScale && elementScale[sizeAttr] !== undefined) {
|
|
318
|
-
// Set the resolved pixel value as a separate attribute
|
|
319
|
-
el.setAttribute("data-size-resolved", `${elementScale[sizeAttr]}px`);
|
|
320
|
-
}
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
56
|
/**
|
|
327
57
|
* Map of data-type to parser function
|
|
328
58
|
*/
|
|
@@ -358,10 +88,10 @@ const PARSER_MAP = {
|
|
|
358
88
|
};
|
|
359
89
|
|
|
360
90
|
/**
|
|
361
|
-
* Create parseElement function
|
|
362
|
-
*
|
|
91
|
+
* Create parseElement function
|
|
92
|
+
* Tracks element-id to internal-id mappings for scroll/show-hide resolution
|
|
363
93
|
*/
|
|
364
|
-
function createParseElement(
|
|
94
|
+
function createParseElement(elementIdMap) {
|
|
365
95
|
function parseElement(element, parentId, index) {
|
|
366
96
|
const dataType = getDataType(element);
|
|
367
97
|
|
|
@@ -388,9 +118,6 @@ function createParseElement(styleguideData, elementIdMap) {
|
|
|
388
118
|
let node;
|
|
389
119
|
if (containerTypes.includes(dataType)) {
|
|
390
120
|
node = parser(element, parentId, index, parseElement);
|
|
391
|
-
} else if (dataType === "Button/V1") {
|
|
392
|
-
// Button needs styleguide data to look up button styles
|
|
393
|
-
node = parser(element, parentId, index, styleguideData);
|
|
394
121
|
} else {
|
|
395
122
|
node = parser(element, parentId, index);
|
|
396
123
|
}
|
|
@@ -455,10 +182,9 @@ function resolveButtonReferences(node, elementIdMap) {
|
|
|
455
182
|
* Parse the entire page tree starting from a root element
|
|
456
183
|
*
|
|
457
184
|
* @param {HTMLElement} rootElement - The root element to parse (default: find ContentNode)
|
|
458
|
-
* @param {Object} styleguideData - Optional styleguide data for applying fonts/colors
|
|
459
185
|
* @returns {Object} The pagetree JSON object
|
|
460
186
|
*/
|
|
461
|
-
export function parsePageTree(rootElement = null
|
|
187
|
+
export function parsePageTree(rootElement = null) {
|
|
462
188
|
// Find the root ContentNode if not provided
|
|
463
189
|
if (!rootElement) {
|
|
464
190
|
rootElement = document.querySelector('[data-type="ContentNode"]');
|
|
@@ -469,16 +195,14 @@ export function parsePageTree(rootElement = null, styleguideData = null) {
|
|
|
469
195
|
return null;
|
|
470
196
|
}
|
|
471
197
|
|
|
472
|
-
//
|
|
473
|
-
// This ensures the parser captures styleguide-applied values (fonts, paint theme colors)
|
|
198
|
+
// Get document root for popup detection
|
|
474
199
|
const docRoot = rootElement.ownerDocument || document;
|
|
475
|
-
applyStyleguideDataAttributes(docRoot, styleguideData);
|
|
476
200
|
|
|
477
201
|
// Create element ID map for scroll/show-hide reference resolution
|
|
478
202
|
const elementIdMap = {};
|
|
479
203
|
|
|
480
|
-
// Create parseElement
|
|
481
|
-
const parseElement = createParseElement(
|
|
204
|
+
// Create parseElement function
|
|
205
|
+
const parseElement = createParseElement(elementIdMap);
|
|
482
206
|
|
|
483
207
|
// Parse the content node
|
|
484
208
|
const content = parseContentNode(rootElement, parseElement);
|
|
@@ -597,7 +321,6 @@ export function parsePageTree(rootElement = null, styleguideData = null) {
|
|
|
597
321
|
".containerModal": {
|
|
598
322
|
attrs: {
|
|
599
323
|
"data-skip-corners-settings": "false",
|
|
600
|
-
"data-style-guide-corner": "style1",
|
|
601
324
|
style: { "margin-bottom": 0 },
|
|
602
325
|
},
|
|
603
326
|
},
|
|
@@ -613,15 +336,10 @@ export function parsePageTree(rootElement = null, styleguideData = null) {
|
|
|
613
336
|
*
|
|
614
337
|
* @param {HTMLElement} rootElement - The root element to parse
|
|
615
338
|
* @param {boolean} pretty - Whether to pretty-print the JSON
|
|
616
|
-
* @param {Object} styleguideData - Optional styleguide data for applying fonts/colors
|
|
617
339
|
* @returns {string} The pagetree as JSON string
|
|
618
340
|
*/
|
|
619
|
-
export function exportPageTreeJSON(
|
|
620
|
-
|
|
621
|
-
pretty = true,
|
|
622
|
-
styleguideData = null
|
|
623
|
-
) {
|
|
624
|
-
const pageTree = parsePageTree(rootElement, styleguideData);
|
|
341
|
+
export function exportPageTreeJSON(rootElement = null, pretty = true) {
|
|
342
|
+
const pageTree = parsePageTree(rootElement);
|
|
625
343
|
if (!pageTree) return null;
|
|
626
344
|
|
|
627
345
|
return pretty ? JSON.stringify(pageTree, null, 2) : JSON.stringify(pageTree);
|
|
@@ -632,14 +350,9 @@ export function exportPageTreeJSON(
|
|
|
632
350
|
*
|
|
633
351
|
* @param {string} filename - The filename (default: 'pagetree.json')
|
|
634
352
|
* @param {HTMLElement} rootElement - The root element to parse
|
|
635
|
-
* @param {Object} styleguideData - Optional styleguide data for applying fonts/colors
|
|
636
353
|
*/
|
|
637
|
-
export function downloadPageTree(
|
|
638
|
-
|
|
639
|
-
rootElement = null,
|
|
640
|
-
styleguideData = null
|
|
641
|
-
) {
|
|
642
|
-
const json = exportPageTreeJSON(rootElement, true, styleguideData);
|
|
354
|
+
export function downloadPageTree(filename = "pagetree.json", rootElement = null) {
|
|
355
|
+
const json = exportPageTreeJSON(rootElement, true);
|
|
643
356
|
if (!json) return;
|
|
644
357
|
|
|
645
358
|
const blob = new Blob([json], { type: "application/json" });
|
|
@@ -658,14 +371,10 @@ export function downloadPageTree(
|
|
|
658
371
|
* Copy pagetree JSON to clipboard
|
|
659
372
|
*
|
|
660
373
|
* @param {HTMLElement} rootElement - The root element to parse
|
|
661
|
-
* @param {Object} styleguideData - Optional styleguide data for applying fonts/colors
|
|
662
374
|
* @returns {Promise<boolean>} Whether the copy was successful
|
|
663
375
|
*/
|
|
664
|
-
export async function copyPageTreeToClipboard(
|
|
665
|
-
|
|
666
|
-
styleguideData = null
|
|
667
|
-
) {
|
|
668
|
-
const json = exportPageTreeJSON(rootElement, true, styleguideData);
|
|
376
|
+
export async function copyPageTreeToClipboard(rootElement = null) {
|
|
377
|
+
const json = exportPageTreeJSON(rootElement, true);
|
|
669
378
|
if (!json) return false;
|
|
670
379
|
|
|
671
380
|
try {
|
package/src/parsers/button.js
CHANGED
|
@@ -34,9 +34,8 @@ import {
|
|
|
34
34
|
* @param {HTMLElement} element - The button element
|
|
35
35
|
* @param {string} parentId - Parent element ID
|
|
36
36
|
* @param {number} index - Child index
|
|
37
|
-
* @param {Object} styleguideData - Optional styleguide data for looking up button styles
|
|
38
37
|
*/
|
|
39
|
-
export function parseButton(element, parentId, index
|
|
38
|
+
export function parseButton(element, parentId, index) {
|
|
40
39
|
const id = generateId();
|
|
41
40
|
const mainTextId = generateId();
|
|
42
41
|
const subTextId = generateId();
|
|
@@ -53,15 +52,6 @@ export function parseButton(element, parentId, index, styleguideData = null) {
|
|
|
53
52
|
const hideIds = element.getAttribute('data-hide-ids');
|
|
54
53
|
const elButtonType = element.getAttribute('data-elbuttontype');
|
|
55
54
|
|
|
56
|
-
// Check for styleguide button
|
|
57
|
-
const styleGuideButton = element.getAttribute('data-style-guide-button');
|
|
58
|
-
|
|
59
|
-
// Look up button style from styleguide if available
|
|
60
|
-
let styleguideButtonStyle = null;
|
|
61
|
-
if (styleGuideButton && styleguideData?.buttons) {
|
|
62
|
-
styleguideButtonStyle = styleguideData.buttons.find(btn => btn.id === styleGuideButton);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
55
|
// Find the anchor element for fallback parsing
|
|
66
56
|
const anchor = element.querySelector('a');
|
|
67
57
|
const anchorStyles = anchor ? parseInlineStyle(anchor.getAttribute('style') || '') : {};
|
|
@@ -70,21 +60,16 @@ export function parseButton(element, parentId, index, styleguideData = null) {
|
|
|
70
60
|
const textSpan = anchor ? anchor.querySelector('span') : null;
|
|
71
61
|
const textStyles = textSpan ? parseInlineStyle(textSpan.getAttribute('style') || '') : {};
|
|
72
62
|
|
|
73
|
-
// Read from
|
|
74
|
-
// Styleguide button structure: { regular: { bg, color }, hover: { bg, color }, borderRadius, borderWidth, borderColor }
|
|
63
|
+
// Read from data attributes first, then inline styles
|
|
75
64
|
const bgAttr = element.getAttribute('data-bg');
|
|
76
|
-
const bgColor =
|
|
77
|
-
? normalizeColor(
|
|
78
|
-
:
|
|
79
|
-
? normalizeColor(bgAttr)
|
|
80
|
-
: (normalizeColor(anchorStyles['background-color']) || '#3b82f6');
|
|
65
|
+
const bgColor = bgAttr
|
|
66
|
+
? normalizeColor(bgAttr)
|
|
67
|
+
: (normalizeColor(anchorStyles['background-color']) || '#3b82f6');
|
|
81
68
|
|
|
82
69
|
const textColorAttr = element.getAttribute('data-color');
|
|
83
|
-
const textColor =
|
|
84
|
-
? normalizeColor(
|
|
85
|
-
:
|
|
86
|
-
? normalizeColor(textColorAttr)
|
|
87
|
-
: (normalizeColor(textStyles.color) || '#ffffff');
|
|
70
|
+
const textColor = textColorAttr
|
|
71
|
+
? normalizeColor(textColorAttr)
|
|
72
|
+
: (normalizeColor(textStyles.color) || '#ffffff');
|
|
88
73
|
|
|
89
74
|
// Font styling - prefer data attributes
|
|
90
75
|
const fontSizeAttr = element.getAttribute('data-size');
|
|
@@ -98,40 +83,26 @@ export function parseButton(element, parentId, index, styleguideData = null) {
|
|
|
98
83
|
const paddingHorizontal = pxAttr ? parseValueWithUnit(pxAttr) : parseValueWithUnit(anchorStyles['padding-right'] || '32px');
|
|
99
84
|
const paddingVertical = pyAttr ? parseValueWithUnit(pyAttr) : parseValueWithUnit(anchorStyles['padding-top'] || '16px');
|
|
100
85
|
|
|
101
|
-
// Border and corners -
|
|
86
|
+
// Border and corners - data attributes first, then inline styles
|
|
102
87
|
const roundedAttr = element.getAttribute('data-rounded');
|
|
103
|
-
const borderRadius =
|
|
104
|
-
?
|
|
105
|
-
:
|
|
106
|
-
? parseValueWithUnit(roundedAttr)
|
|
107
|
-
: parseBorderRadius(anchorStyles);
|
|
88
|
+
const borderRadius = roundedAttr
|
|
89
|
+
? parseValueWithUnit(roundedAttr)
|
|
90
|
+
: parseBorderRadius(anchorStyles);
|
|
108
91
|
|
|
109
92
|
const borderColorAttr = element.getAttribute('data-border-color');
|
|
110
|
-
const borderColor =
|
|
111
|
-
? normalizeColor(
|
|
112
|
-
:
|
|
113
|
-
? normalizeColor(borderColorAttr)
|
|
114
|
-
: normalizeColor(anchorStyles['border-color']);
|
|
93
|
+
const borderColor = borderColorAttr
|
|
94
|
+
? normalizeColor(borderColorAttr)
|
|
95
|
+
: normalizeColor(anchorStyles['border-color']);
|
|
115
96
|
|
|
116
97
|
const borderWidthAttr = element.getAttribute('data-border-width');
|
|
117
|
-
const borderWidth =
|
|
118
|
-
?
|
|
119
|
-
:
|
|
120
|
-
? parseValueWithUnit(borderWidthAttr)
|
|
121
|
-
: parseValueWithUnit(anchorStyles['border-width'] || '0');
|
|
98
|
+
const borderWidth = borderWidthAttr
|
|
99
|
+
? parseValueWithUnit(borderWidthAttr)
|
|
100
|
+
: parseValueWithUnit(anchorStyles['border-width'] || '0');
|
|
122
101
|
|
|
123
102
|
// Shadow
|
|
124
103
|
const shadowAttr = element.getAttribute('data-shadow');
|
|
125
104
|
const shadow = shadowAttr ? parseShadow(shadowAttr) : parseShadow(anchorStyles['box-shadow']);
|
|
126
105
|
|
|
127
|
-
// Hover state from styleguide
|
|
128
|
-
const hoverBgColor = styleguideButtonStyle?.hover?.bg
|
|
129
|
-
? normalizeColor(styleguideButtonStyle.hover.bg)
|
|
130
|
-
: null;
|
|
131
|
-
const hoverTextColor = styleguideButtonStyle?.hover?.color
|
|
132
|
-
? normalizeColor(styleguideButtonStyle.hover.color)
|
|
133
|
-
: null;
|
|
134
|
-
|
|
135
106
|
// Alignment
|
|
136
107
|
const textAlign = element.getAttribute('data-align') || parseTextAlign(wrapperStyles['text-align']);
|
|
137
108
|
|
|
@@ -165,7 +136,6 @@ export function parseButton(element, parentId, index, styleguideData = null) {
|
|
|
165
136
|
const fullWidth = element.getAttribute('data-full-width') === 'true';
|
|
166
137
|
|
|
167
138
|
// Build button selector - always include padding params
|
|
168
|
-
// When using styleguide button, also include data-style-guide-button attribute
|
|
169
139
|
const buttonSelector = {
|
|
170
140
|
attrs: {
|
|
171
141
|
style: {},
|
|
@@ -175,7 +145,6 @@ export function parseButton(element, parentId, index, styleguideData = null) {
|
|
|
175
145
|
'--style-padding-horizontal--unit': paddingHorizontal ? paddingHorizontal.unit : 'px',
|
|
176
146
|
'--style-padding-vertical': paddingVertical ? paddingVertical.value : 16,
|
|
177
147
|
'--style-padding-vertical--unit': paddingVertical ? paddingVertical.unit : 'px',
|
|
178
|
-
'style-guide-override-button': true,
|
|
179
148
|
'--style-background-color': bgColor,
|
|
180
149
|
'--style-border-color': borderColor || 'transparent',
|
|
181
150
|
'--style-border-width': borderWidth ? borderWidth.value : 0,
|
|
@@ -183,11 +152,6 @@ export function parseButton(element, parentId, index, styleguideData = null) {
|
|
|
183
152
|
},
|
|
184
153
|
};
|
|
185
154
|
|
|
186
|
-
// Add styleguide button reference if present
|
|
187
|
-
if (styleGuideButton) {
|
|
188
|
-
buttonSelector.attrs['data-style-guide-button'] = styleGuideButton;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
155
|
// Parse animation attributes
|
|
192
156
|
const { attrs: animationAttrs, params: animationParams } = parseAnimationAttrs(element);
|
|
193
157
|
|
|
@@ -354,26 +318,5 @@ export function parseButton(element, parentId, index, styleguideData = null) {
|
|
|
354
318
|
node.selectors['.elButton .elButtonSub'].attrs.style.color = subTextColor;
|
|
355
319
|
}
|
|
356
320
|
|
|
357
|
-
// Add hover state selectors if available from styleguide
|
|
358
|
-
if (hoverBgColor) {
|
|
359
|
-
node.selectors['.elButton:hover'] = {
|
|
360
|
-
attrs: {
|
|
361
|
-
style: {},
|
|
362
|
-
},
|
|
363
|
-
params: {
|
|
364
|
-
'--style-background-color': hoverBgColor,
|
|
365
|
-
},
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
if (hoverTextColor) {
|
|
369
|
-
node.selectors['.elButton:hover .elButtonText'] = {
|
|
370
|
-
attrs: {
|
|
371
|
-
style: {
|
|
372
|
-
color: hoverTextColor,
|
|
373
|
-
},
|
|
374
|
-
},
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
|
|
378
321
|
return node;
|
|
379
322
|
}
|
package/src/parsers/layout.js
CHANGED
|
@@ -90,7 +90,6 @@ export function parseSectionContainer(element, parentId, index, parseChildren) {
|
|
|
90
90
|
marginTop: spacing.marginTop || parseValueWithUnit('0px'),
|
|
91
91
|
};
|
|
92
92
|
const overlay = element.getAttribute('data-overlay');
|
|
93
|
-
const paintColors = element.getAttribute('data-paint-colors');
|
|
94
93
|
|
|
95
94
|
// Video background attributes
|
|
96
95
|
const videoBgUrl = element.getAttribute('data-video-bg-url');
|
|
@@ -134,11 +133,6 @@ export function parseSectionContainer(element, parentId, index, parseChildren) {
|
|
|
134
133
|
node.attrs.id = elementId;
|
|
135
134
|
}
|
|
136
135
|
|
|
137
|
-
// Add paint colors if present
|
|
138
|
-
if (paintColors) {
|
|
139
|
-
node.attrs['data-paint-colors'] = paintColors;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
136
|
// Apply spacing
|
|
143
137
|
const { attrs: spacingAttrs, params: spacingParams } = spacingToAttrsAndParams(rowSpacingWithDefaults);
|
|
144
138
|
Object.assign(node.attrs.style, spacingAttrs.style);
|
|
@@ -267,7 +261,6 @@ export function parseRowContainer(element, parentId, index, parseChildren) {
|
|
|
267
261
|
marginTop: spacing.marginTop || parseValueWithUnit('0px'),
|
|
268
262
|
};
|
|
269
263
|
const overlay = element.getAttribute('data-overlay');
|
|
270
|
-
const paintColors = element.getAttribute('data-paint-colors');
|
|
271
264
|
|
|
272
265
|
const width = parseValueWithUnit(styles.width || '1170px');
|
|
273
266
|
|
|
@@ -322,11 +315,6 @@ export function parseRowContainer(element, parentId, index, parseChildren) {
|
|
|
322
315
|
node.attrs.id = elementId;
|
|
323
316
|
}
|
|
324
317
|
|
|
325
|
-
// Add paint colors if present
|
|
326
|
-
if (paintColors) {
|
|
327
|
-
node.attrs['data-paint-colors'] = paintColors;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
318
|
// Add className if set
|
|
331
319
|
if (className) {
|
|
332
320
|
node.attrs.className = className;
|
|
@@ -470,7 +458,6 @@ export function parseColContainer(element, parentId, index, parseChildren) {
|
|
|
470
458
|
const overlay = colInner.getAttribute('data-overlay');
|
|
471
459
|
const separateCorners = colInner.getAttribute('data-separate-corners') === 'true';
|
|
472
460
|
const borderRadius = parseBorderRadius(innerStyles);
|
|
473
|
-
const paintColors = colInner.getAttribute('data-paint-colors');
|
|
474
461
|
|
|
475
462
|
const colInnerSelector = node.selectors['& > .col-inner'];
|
|
476
463
|
|
|
@@ -586,11 +573,6 @@ export function parseColContainer(element, parentId, index, parseChildren) {
|
|
|
586
573
|
colInnerSelector.attrs['data-skip-background-settings'] =
|
|
587
574
|
(hasBackground || overlay) ? 'false' : 'true';
|
|
588
575
|
|
|
589
|
-
// Add paint colors if present
|
|
590
|
-
if (paintColors) {
|
|
591
|
-
colInnerSelector.attrs['data-paint-colors'] = paintColors;
|
|
592
|
-
}
|
|
593
|
-
|
|
594
576
|
// Parse children from col-inner, skipping overlay and content wrapper
|
|
595
577
|
let childIdx = 0;
|
|
596
578
|
const parseColInnerChildren = (container) => {
|
|
@@ -650,7 +632,6 @@ export function parseFlexContainer(element, parentId, index, parseChildren) {
|
|
|
650
632
|
marginTop: spacing.marginTop || parseValueWithUnit('0px'),
|
|
651
633
|
};
|
|
652
634
|
const overlay = element.getAttribute('data-overlay');
|
|
653
|
-
const paintColors = element.getAttribute('data-paint-colors');
|
|
654
635
|
|
|
655
636
|
const width = parseValueWithUnit(styles.width || '100%', '%');
|
|
656
637
|
const height = styles.height ? parseValueWithUnit(styles.height, 'px') : null;
|
|
@@ -692,11 +673,6 @@ export function parseFlexContainer(element, parentId, index, parseChildren) {
|
|
|
692
673
|
node.attrs.id = elementId;
|
|
693
674
|
}
|
|
694
675
|
|
|
695
|
-
// Add paint colors if present
|
|
696
|
-
if (paintColors) {
|
|
697
|
-
node.attrs['data-paint-colors'] = paintColors;
|
|
698
|
-
}
|
|
699
|
-
|
|
700
676
|
// Add width
|
|
701
677
|
node.attrs.style.width = width.value;
|
|
702
678
|
node.params['width--unit'] = width.unit;
|
package/src/parsers/list.js
CHANGED
|
@@ -44,8 +44,6 @@ export function parseCheckoutPlaceholder(element, parentId, index) {
|
|
|
44
44
|
fractionalIndex: generateFractionalIndex(index),
|
|
45
45
|
attrs: {
|
|
46
46
|
style: {
|
|
47
|
-
'--container-font-family': 'var(--style-guide-font-family-content)',
|
|
48
|
-
'--input-headline-font-family': 'var(--style-guide-font-family-subheadline)',
|
|
49
47
|
'--multiple-payments-font-family': 'sans-serif',
|
|
50
48
|
'--input-background-color': '#FFFFFF',
|
|
51
49
|
},
|