docgen-utils 1.0.30 → 1.0.31
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/bundle.js +212 -45
- package/dist/bundle.min.js +99 -99
- package/dist/packages/slides/parse.d.ts.map +1 -1
- package/dist/packages/slides/parse.js +211 -8
- package/dist/packages/slides/parse.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../packages/slides/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,OAAO,KAAK,EACV,WAAW,EAeZ,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../packages/slides/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,OAAO,KAAK,EACV,WAAW,EAeZ,MAAM,UAAU,CAAC;AAwmFlB;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW,CAyyKzD"}
|
|
@@ -85,6 +85,39 @@ function extractZIndex(computed) {
|
|
|
85
85
|
return undefined;
|
|
86
86
|
return parsed;
|
|
87
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Get the effective z-index for an element, considering stacking context inheritance.
|
|
90
|
+
*
|
|
91
|
+
* In CSS, z-index only applies to positioned elements (absolute, relative, fixed, sticky).
|
|
92
|
+
* Child elements participate in their ancestor's stacking context. This function walks
|
|
93
|
+
* up the DOM tree to find the nearest stacking context (positioned element with z-index)
|
|
94
|
+
* and returns that z-index value.
|
|
95
|
+
*
|
|
96
|
+
* This is needed because when parsing individual elements, a text element inside a
|
|
97
|
+
* z-index:10 container doesn't have its own z-index, but visually appears at z-index:10.
|
|
98
|
+
*
|
|
99
|
+
* @param element - The element to check
|
|
100
|
+
* @param win - The window object for getComputedStyle
|
|
101
|
+
* @returns The effective z-index from the nearest stacking context, or undefined if none
|
|
102
|
+
*/
|
|
103
|
+
function getEffectiveZIndex(element, win) {
|
|
104
|
+
let current = element;
|
|
105
|
+
while (current && current !== win.document.body && current !== win.document.documentElement) {
|
|
106
|
+
const computed = win.getComputedStyle(current);
|
|
107
|
+
const position = computed.position;
|
|
108
|
+
// Check if this element creates a stacking context (positioned with z-index)
|
|
109
|
+
const isPositioned = position === 'absolute' || position === 'relative' ||
|
|
110
|
+
position === 'fixed' || position === 'sticky';
|
|
111
|
+
if (isPositioned) {
|
|
112
|
+
const zIndex = extractZIndex(computed);
|
|
113
|
+
if (zIndex !== undefined) {
|
|
114
|
+
return zIndex;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
current = current.parentElement;
|
|
118
|
+
}
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
88
121
|
/**
|
|
89
122
|
* Compute the effective (accumulated) opacity for an element by multiplying
|
|
90
123
|
* the element's own opacity with all ancestor opacities.
|
|
@@ -2623,7 +2656,7 @@ export function parseSlideHtml(doc) {
|
|
|
2623
2656
|
cssTriangle: null,
|
|
2624
2657
|
customGeometry: null,
|
|
2625
2658
|
},
|
|
2626
|
-
zIndex:
|
|
2659
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
2627
2660
|
};
|
|
2628
2661
|
elements.push(shapeElement);
|
|
2629
2662
|
// Handle accent borders (border-left/border-right) that are thicker than the base
|
|
@@ -2723,6 +2756,7 @@ export function parseSlideHtml(doc) {
|
|
|
2723
2756
|
cssTriangle: null,
|
|
2724
2757
|
customGeometry: points,
|
|
2725
2758
|
},
|
|
2759
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
2726
2760
|
};
|
|
2727
2761
|
elements.push(borderLeftShape);
|
|
2728
2762
|
}
|
|
@@ -2753,6 +2787,7 @@ export function parseSlideHtml(doc) {
|
|
|
2753
2787
|
cssTriangle: null,
|
|
2754
2788
|
customGeometry: null,
|
|
2755
2789
|
},
|
|
2790
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
2756
2791
|
};
|
|
2757
2792
|
elements.push(borderLeftShape);
|
|
2758
2793
|
}
|
|
@@ -2830,6 +2865,7 @@ export function parseSlideHtml(doc) {
|
|
|
2830
2865
|
cssTriangle: null,
|
|
2831
2866
|
customGeometry: points,
|
|
2832
2867
|
},
|
|
2868
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
2833
2869
|
};
|
|
2834
2870
|
elements.push(borderRightShape);
|
|
2835
2871
|
}
|
|
@@ -2859,6 +2895,7 @@ export function parseSlideHtml(doc) {
|
|
|
2859
2895
|
cssTriangle: null,
|
|
2860
2896
|
customGeometry: null,
|
|
2861
2897
|
},
|
|
2898
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
2862
2899
|
};
|
|
2863
2900
|
elements.push(borderRightShape);
|
|
2864
2901
|
}
|
|
@@ -2940,6 +2977,7 @@ export function parseSlideHtml(doc) {
|
|
|
2940
2977
|
cssTriangle: null,
|
|
2941
2978
|
customGeometry: points,
|
|
2942
2979
|
},
|
|
2980
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
2943
2981
|
};
|
|
2944
2982
|
elements.push(borderTopShape);
|
|
2945
2983
|
}
|
|
@@ -2969,6 +3007,7 @@ export function parseSlideHtml(doc) {
|
|
|
2969
3007
|
cssTriangle: null,
|
|
2970
3008
|
customGeometry: null,
|
|
2971
3009
|
},
|
|
3010
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
2972
3011
|
};
|
|
2973
3012
|
elements.push(borderTopShape);
|
|
2974
3013
|
}
|
|
@@ -3043,6 +3082,7 @@ export function parseSlideHtml(doc) {
|
|
|
3043
3082
|
cssTriangle: null,
|
|
3044
3083
|
customGeometry: points,
|
|
3045
3084
|
},
|
|
3085
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
3046
3086
|
};
|
|
3047
3087
|
elements.push(borderBottomShape);
|
|
3048
3088
|
}
|
|
@@ -3072,6 +3112,7 @@ export function parseSlideHtml(doc) {
|
|
|
3072
3112
|
cssTriangle: null,
|
|
3073
3113
|
customGeometry: null,
|
|
3074
3114
|
},
|
|
3115
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
3075
3116
|
};
|
|
3076
3117
|
elements.push(borderBottomShape);
|
|
3077
3118
|
}
|
|
@@ -3212,7 +3253,7 @@ export function parseSlideHtml(doc) {
|
|
|
3212
3253
|
cssTriangle: null,
|
|
3213
3254
|
customGeometry: null,
|
|
3214
3255
|
},
|
|
3215
|
-
zIndex:
|
|
3256
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
3216
3257
|
};
|
|
3217
3258
|
elements.push(shapeElement);
|
|
3218
3259
|
// Handle accent borders (border-left/border-right) that are thicker than the base
|
|
@@ -3312,6 +3353,7 @@ export function parseSlideHtml(doc) {
|
|
|
3312
3353
|
cssTriangle: null,
|
|
3313
3354
|
customGeometry: points,
|
|
3314
3355
|
},
|
|
3356
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
3315
3357
|
};
|
|
3316
3358
|
elements.push(borderLeftShape);
|
|
3317
3359
|
}
|
|
@@ -3342,6 +3384,7 @@ export function parseSlideHtml(doc) {
|
|
|
3342
3384
|
cssTriangle: null,
|
|
3343
3385
|
customGeometry: null,
|
|
3344
3386
|
},
|
|
3387
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
3345
3388
|
};
|
|
3346
3389
|
elements.push(borderLeftShape);
|
|
3347
3390
|
}
|
|
@@ -3419,6 +3462,7 @@ export function parseSlideHtml(doc) {
|
|
|
3419
3462
|
cssTriangle: null,
|
|
3420
3463
|
customGeometry: points,
|
|
3421
3464
|
},
|
|
3465
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
3422
3466
|
};
|
|
3423
3467
|
elements.push(borderRightShape);
|
|
3424
3468
|
}
|
|
@@ -3448,6 +3492,7 @@ export function parseSlideHtml(doc) {
|
|
|
3448
3492
|
cssTriangle: null,
|
|
3449
3493
|
customGeometry: null,
|
|
3450
3494
|
},
|
|
3495
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
3451
3496
|
};
|
|
3452
3497
|
elements.push(borderRightShape);
|
|
3453
3498
|
}
|
|
@@ -3529,6 +3574,7 @@ export function parseSlideHtml(doc) {
|
|
|
3529
3574
|
cssTriangle: null,
|
|
3530
3575
|
customGeometry: points,
|
|
3531
3576
|
},
|
|
3577
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
3532
3578
|
};
|
|
3533
3579
|
elements.push(borderTopShape);
|
|
3534
3580
|
}
|
|
@@ -3558,6 +3604,7 @@ export function parseSlideHtml(doc) {
|
|
|
3558
3604
|
cssTriangle: null,
|
|
3559
3605
|
customGeometry: null,
|
|
3560
3606
|
},
|
|
3607
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
3561
3608
|
};
|
|
3562
3609
|
elements.push(borderTopShape);
|
|
3563
3610
|
}
|
|
@@ -3724,6 +3771,7 @@ export function parseSlideHtml(doc) {
|
|
|
3724
3771
|
fontFill: spanFontFill,
|
|
3725
3772
|
...(extractAlpha(computed2.color) !== null ? { transparency: extractAlpha(computed2.color) } : {}),
|
|
3726
3773
|
},
|
|
3774
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
3727
3775
|
};
|
|
3728
3776
|
elements.push(textElement);
|
|
3729
3777
|
processed.add(el);
|
|
@@ -3923,6 +3971,11 @@ export function parseSlideHtml(doc) {
|
|
|
3923
3971
|
if (hasOpacity && !maskApplied) {
|
|
3924
3972
|
imageElement.transparency = Math.round((1 - imgOpacity) * 100);
|
|
3925
3973
|
}
|
|
3974
|
+
// Add z-index for stacking order
|
|
3975
|
+
const imgZIndex = getEffectiveZIndex(el, win);
|
|
3976
|
+
if (imgZIndex !== undefined) {
|
|
3977
|
+
imageElement.zIndex = imgZIndex;
|
|
3978
|
+
}
|
|
3926
3979
|
elements.push(imageElement);
|
|
3927
3980
|
processed.add(el);
|
|
3928
3981
|
return;
|
|
@@ -4137,6 +4190,7 @@ export function parseSlideHtml(doc) {
|
|
|
4137
4190
|
},
|
|
4138
4191
|
sizing: null,
|
|
4139
4192
|
transparency: svgEffectiveOpacity < 1 ? Math.round((1 - svgEffectiveOpacity) * 100) : undefined,
|
|
4193
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4140
4194
|
};
|
|
4141
4195
|
elements.push(imageElement);
|
|
4142
4196
|
processed.add(el);
|
|
@@ -4228,6 +4282,7 @@ export function parseSlideHtml(doc) {
|
|
|
4228
4282
|
h: pxToInch(rect.height),
|
|
4229
4283
|
},
|
|
4230
4284
|
sizing: null,
|
|
4285
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4231
4286
|
};
|
|
4232
4287
|
elements.push(imageElement);
|
|
4233
4288
|
}
|
|
@@ -4270,6 +4325,7 @@ export function parseSlideHtml(doc) {
|
|
|
4270
4325
|
},
|
|
4271
4326
|
sizing: null,
|
|
4272
4327
|
rectRadius: 0,
|
|
4328
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4273
4329
|
};
|
|
4274
4330
|
elements.push(imgElement);
|
|
4275
4331
|
processed.add(el);
|
|
@@ -4304,6 +4360,7 @@ export function parseSlideHtml(doc) {
|
|
|
4304
4360
|
},
|
|
4305
4361
|
sizing: null,
|
|
4306
4362
|
rectRadius: 0,
|
|
4363
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4307
4364
|
};
|
|
4308
4365
|
elements.push(imgElement);
|
|
4309
4366
|
hasConicGradientImage = true;
|
|
@@ -4400,6 +4457,7 @@ export function parseSlideHtml(doc) {
|
|
|
4400
4457
|
cssTriangle: { direction: triangleDirection },
|
|
4401
4458
|
customGeometry: null,
|
|
4402
4459
|
},
|
|
4460
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4403
4461
|
};
|
|
4404
4462
|
elements.push(triangleShape);
|
|
4405
4463
|
processed.add(el);
|
|
@@ -4450,6 +4508,7 @@ export function parseSlideHtml(doc) {
|
|
|
4450
4508
|
sizing: null,
|
|
4451
4509
|
rectRadius: 0,
|
|
4452
4510
|
transparency: effOp < 1 ? Math.round((1 - effOp) * 100) : undefined,
|
|
4511
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4453
4512
|
};
|
|
4454
4513
|
elements.push(imgElement);
|
|
4455
4514
|
}
|
|
@@ -4591,6 +4650,7 @@ export function parseSlideHtml(doc) {
|
|
|
4591
4650
|
cssTriangle: null,
|
|
4592
4651
|
customGeometry: points,
|
|
4593
4652
|
},
|
|
4653
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4594
4654
|
});
|
|
4595
4655
|
}
|
|
4596
4656
|
else {
|
|
@@ -4620,6 +4680,7 @@ export function parseSlideHtml(doc) {
|
|
|
4620
4680
|
cssTriangle: null,
|
|
4621
4681
|
customGeometry: null,
|
|
4622
4682
|
},
|
|
4683
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4623
4684
|
});
|
|
4624
4685
|
}
|
|
4625
4686
|
}
|
|
@@ -4710,6 +4771,7 @@ export function parseSlideHtml(doc) {
|
|
|
4710
4771
|
cssTriangle: null,
|
|
4711
4772
|
customGeometry: points,
|
|
4712
4773
|
},
|
|
4774
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4713
4775
|
});
|
|
4714
4776
|
}
|
|
4715
4777
|
else {
|
|
@@ -4738,6 +4800,7 @@ export function parseSlideHtml(doc) {
|
|
|
4738
4800
|
cssTriangle: null,
|
|
4739
4801
|
customGeometry: null,
|
|
4740
4802
|
},
|
|
4803
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4741
4804
|
});
|
|
4742
4805
|
}
|
|
4743
4806
|
}
|
|
@@ -4825,6 +4888,7 @@ export function parseSlideHtml(doc) {
|
|
|
4825
4888
|
cssTriangle: null,
|
|
4826
4889
|
customGeometry: points,
|
|
4827
4890
|
},
|
|
4891
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4828
4892
|
});
|
|
4829
4893
|
}
|
|
4830
4894
|
else {
|
|
@@ -4853,6 +4917,7 @@ export function parseSlideHtml(doc) {
|
|
|
4853
4917
|
cssTriangle: null,
|
|
4854
4918
|
customGeometry: null,
|
|
4855
4919
|
},
|
|
4920
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4856
4921
|
});
|
|
4857
4922
|
}
|
|
4858
4923
|
}
|
|
@@ -4936,6 +5001,7 @@ export function parseSlideHtml(doc) {
|
|
|
4936
5001
|
cssTriangle: null,
|
|
4937
5002
|
customGeometry: points,
|
|
4938
5003
|
},
|
|
5004
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4939
5005
|
});
|
|
4940
5006
|
}
|
|
4941
5007
|
else {
|
|
@@ -4964,6 +5030,7 @@ export function parseSlideHtml(doc) {
|
|
|
4964
5030
|
cssTriangle: null,
|
|
4965
5031
|
customGeometry: null,
|
|
4966
5032
|
},
|
|
5033
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4967
5034
|
});
|
|
4968
5035
|
}
|
|
4969
5036
|
}
|
|
@@ -4991,6 +5058,7 @@ export function parseSlideHtml(doc) {
|
|
|
4991
5058
|
: 'cover',
|
|
4992
5059
|
position: bgImagePosition,
|
|
4993
5060
|
},
|
|
5061
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
4994
5062
|
};
|
|
4995
5063
|
elements.push(bgImgElement);
|
|
4996
5064
|
}
|
|
@@ -6252,7 +6320,7 @@ export function parseSlideHtml(doc) {
|
|
|
6252
6320
|
return points;
|
|
6253
6321
|
})() : null),
|
|
6254
6322
|
},
|
|
6255
|
-
zIndex:
|
|
6323
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
6256
6324
|
};
|
|
6257
6325
|
// Apply CSS padding as text body insets when shape has text content
|
|
6258
6326
|
if (hasPadding && shapeElement.style && (shapeText || (shapeTextRuns && shapeTextRuns.length > 0))) {
|
|
@@ -6296,6 +6364,67 @@ export function parseSlideHtml(doc) {
|
|
|
6296
6364
|
tc.querySelectorAll('*').forEach(desc => processed.delete(desc));
|
|
6297
6365
|
});
|
|
6298
6366
|
}
|
|
6367
|
+
// When a flex container has direct text nodes that weren't merged into the shape,
|
|
6368
|
+
// extract them as separate text elements. This handles cases like:
|
|
6369
|
+
// <div class="flex"><svg>...</svg>Label Text<span>...</span></div>
|
|
6370
|
+
// where "Label Text" is a direct text node between other elements.
|
|
6371
|
+
if (!shouldMergeText && hasDirectText && directTextContent) {
|
|
6372
|
+
// Calculate approximate position for the direct text
|
|
6373
|
+
// For flex-row, text appears after any preceding elements
|
|
6374
|
+
// We use a Range to get the exact bounding box of the text nodes
|
|
6375
|
+
const range = win.document.createRange();
|
|
6376
|
+
let foundTextNode = false;
|
|
6377
|
+
// Find the text nodes and calculate their bounding rect
|
|
6378
|
+
for (const node of Array.from(el.childNodes)) {
|
|
6379
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
6380
|
+
const text = (node.textContent || '').trim();
|
|
6381
|
+
if (text) {
|
|
6382
|
+
if (!foundTextNode) {
|
|
6383
|
+
range.setStart(node, 0);
|
|
6384
|
+
foundTextNode = true;
|
|
6385
|
+
}
|
|
6386
|
+
range.setEnd(node, node.textContent?.length || 0);
|
|
6387
|
+
}
|
|
6388
|
+
}
|
|
6389
|
+
}
|
|
6390
|
+
if (foundTextNode) {
|
|
6391
|
+
const textRect = range.getBoundingClientRect();
|
|
6392
|
+
if (textRect.width > 0 && textRect.height > 0) {
|
|
6393
|
+
const isBold = parseInt(computed.fontWeight) >= 600;
|
|
6394
|
+
const isItalic = computed.fontStyle === 'italic';
|
|
6395
|
+
const isUnderline = computed.textDecoration && computed.textDecoration.includes('underline');
|
|
6396
|
+
// Apply text-transform
|
|
6397
|
+
let displayText = directTextContent;
|
|
6398
|
+
if (computed.textTransform && computed.textTransform !== 'none') {
|
|
6399
|
+
displayText = applyTextTransform(displayText, computed.textTransform);
|
|
6400
|
+
}
|
|
6401
|
+
const directTextElement = {
|
|
6402
|
+
type: 'p',
|
|
6403
|
+
text: displayText,
|
|
6404
|
+
position: {
|
|
6405
|
+
x: pxToInch(textRect.left),
|
|
6406
|
+
y: pxToInch(textRect.top),
|
|
6407
|
+
w: pxToInch(textRect.width),
|
|
6408
|
+
h: pxToInch(textRect.height),
|
|
6409
|
+
},
|
|
6410
|
+
style: {
|
|
6411
|
+
fontSize: pxToPoints(computed.fontSize),
|
|
6412
|
+
fontFace: extractFontFace(computed.fontFamily),
|
|
6413
|
+
color: rgbToHex(computed.color),
|
|
6414
|
+
bold: isBold,
|
|
6415
|
+
italic: isItalic,
|
|
6416
|
+
underline: isUnderline ? true : undefined,
|
|
6417
|
+
valign: 'middle',
|
|
6418
|
+
align: 'left',
|
|
6419
|
+
...(extractLetterSpacing(computed) !== null ? { charSpacing: extractLetterSpacing(computed) } : {}),
|
|
6420
|
+
...(extractAlpha(computed.color) !== null ? { transparency: extractAlpha(computed.color) } : {}),
|
|
6421
|
+
},
|
|
6422
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
6423
|
+
};
|
|
6424
|
+
elements.push(directTextElement);
|
|
6425
|
+
}
|
|
6426
|
+
}
|
|
6427
|
+
}
|
|
6299
6428
|
// If we split text from a clipped shape, create a separate text-only shape
|
|
6300
6429
|
// Note: PPTX does NOT clip text to custom geometry paths - text is rendered
|
|
6301
6430
|
// within the bounding box regardless of the path shape. So we DON'T apply
|
|
@@ -6345,6 +6474,7 @@ export function parseSlideHtml(doc) {
|
|
|
6345
6474
|
cssTriangle: null,
|
|
6346
6475
|
customGeometry: null, // NO custom geometry - PPTX doesn't clip text to paths
|
|
6347
6476
|
},
|
|
6477
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
6348
6478
|
};
|
|
6349
6479
|
// Apply CSS padding as text body insets
|
|
6350
6480
|
if (hasPadding && clippedTextShape.style) {
|
|
@@ -6387,6 +6517,7 @@ export function parseSlideHtml(doc) {
|
|
|
6387
6517
|
cssTriangle: null,
|
|
6388
6518
|
customGeometry: null,
|
|
6389
6519
|
},
|
|
6520
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
6390
6521
|
};
|
|
6391
6522
|
elements.push(extraShape);
|
|
6392
6523
|
}
|
|
@@ -6572,6 +6703,66 @@ export function parseSlideHtml(doc) {
|
|
|
6572
6703
|
// Fallback to direct text only if there are structural children
|
|
6573
6704
|
extractedText = directText;
|
|
6574
6705
|
}
|
|
6706
|
+
// Handle flex-row containers with direct text nodes AND structural children
|
|
6707
|
+
// (e.g., <div class="flex"><svg>...</svg>Label Text<span>...</span></div>)
|
|
6708
|
+
// In this case, extract the direct text nodes as a separate element
|
|
6709
|
+
// using Range API to get precise positioning
|
|
6710
|
+
if (isPlainDivFlexRow && directText && hasStructuralChildren) {
|
|
6711
|
+
// Use Range API to get the bounding box of direct text nodes
|
|
6712
|
+
const range = win.document.createRange();
|
|
6713
|
+
let foundTextNode = false;
|
|
6714
|
+
for (const node of Array.from(el.childNodes)) {
|
|
6715
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
6716
|
+
const text = (node.textContent || '').trim();
|
|
6717
|
+
if (text) {
|
|
6718
|
+
if (!foundTextNode) {
|
|
6719
|
+
range.setStart(node, 0);
|
|
6720
|
+
foundTextNode = true;
|
|
6721
|
+
}
|
|
6722
|
+
range.setEnd(node, node.textContent?.length || 0);
|
|
6723
|
+
}
|
|
6724
|
+
}
|
|
6725
|
+
}
|
|
6726
|
+
if (foundTextNode) {
|
|
6727
|
+
const textRect = range.getBoundingClientRect();
|
|
6728
|
+
if (textRect.width > 0 && textRect.height > 0) {
|
|
6729
|
+
const computed2 = win.getComputedStyle(el);
|
|
6730
|
+
const isBold = parseInt(computed2.fontWeight) >= 600;
|
|
6731
|
+
const isItalic = computed2.fontStyle === 'italic';
|
|
6732
|
+
const isUnderline = computed2.textDecoration && computed2.textDecoration.includes('underline');
|
|
6733
|
+
// Apply text-transform
|
|
6734
|
+
let displayText = directText;
|
|
6735
|
+
if (computed2.textTransform && computed2.textTransform !== 'none') {
|
|
6736
|
+
displayText = applyTextTransform(displayText, computed2.textTransform);
|
|
6737
|
+
}
|
|
6738
|
+
const flexDirectTextElement = {
|
|
6739
|
+
type: 'p',
|
|
6740
|
+
text: displayText,
|
|
6741
|
+
position: {
|
|
6742
|
+
x: pxToInch(textRect.left),
|
|
6743
|
+
y: pxToInch(textRect.top),
|
|
6744
|
+
w: pxToInch(textRect.width),
|
|
6745
|
+
h: pxToInch(textRect.height),
|
|
6746
|
+
},
|
|
6747
|
+
style: {
|
|
6748
|
+
fontSize: pxToPoints(computed2.fontSize),
|
|
6749
|
+
fontFace: extractFontFace(computed2.fontFamily),
|
|
6750
|
+
color: rgbToHex(computed2.color),
|
|
6751
|
+
bold: isBold,
|
|
6752
|
+
italic: isItalic,
|
|
6753
|
+
underline: isUnderline ? true : undefined,
|
|
6754
|
+
valign: 'middle',
|
|
6755
|
+
align: 'left',
|
|
6756
|
+
...(extractLetterSpacing(computed2) !== null ? { charSpacing: extractLetterSpacing(computed2) } : {}),
|
|
6757
|
+
...(extractAlpha(computed2.color) !== null ? { transparency: extractAlpha(computed2.color) } : {}),
|
|
6758
|
+
},
|
|
6759
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
6760
|
+
};
|
|
6761
|
+
elements.push(flexDirectTextElement);
|
|
6762
|
+
// Don't mark as processed - structural children still need extraction
|
|
6763
|
+
}
|
|
6764
|
+
}
|
|
6765
|
+
}
|
|
6575
6766
|
if (extractedText && !hasStructuralChildren) {
|
|
6576
6767
|
const computed2 = win.getComputedStyle(el);
|
|
6577
6768
|
const fontSizePx = parseFloat(computed2.fontSize);
|
|
@@ -6752,6 +6943,7 @@ export function parseSlideHtml(doc) {
|
|
|
6752
6943
|
? [paddingLeft * PT_PER_PX, paddingRight * PT_PER_PX, paddingBottom * PT_PER_PX, paddingTop * PT_PER_PX]
|
|
6753
6944
|
: undefined,
|
|
6754
6945
|
},
|
|
6946
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
6755
6947
|
};
|
|
6756
6948
|
// Set element-level transparency (computed from color alpha + CSS opacity)
|
|
6757
6949
|
// This mirrors what we set in baseRunOptions.transparency but also
|
|
@@ -6862,6 +7054,7 @@ export function parseSlideHtml(doc) {
|
|
|
6862
7054
|
valign: 'top',
|
|
6863
7055
|
lineSpacing: pxToPoints(liComputed.lineHeight),
|
|
6864
7056
|
},
|
|
7057
|
+
zIndex: getEffectiveZIndex(liEl, win),
|
|
6865
7058
|
};
|
|
6866
7059
|
elements.push(textElement);
|
|
6867
7060
|
processed.add(liEl);
|
|
@@ -6915,6 +7108,7 @@ export function parseSlideHtml(doc) {
|
|
|
6915
7108
|
paraSpaceAfter: pxToPoints(liComputed.marginBottom),
|
|
6916
7109
|
margin: [marginLeft, 0, 0, 0],
|
|
6917
7110
|
},
|
|
7111
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
6918
7112
|
};
|
|
6919
7113
|
elements.push(listElement);
|
|
6920
7114
|
liElements.forEach((li) => processed.add(li));
|
|
@@ -7240,6 +7434,7 @@ export function parseSlideHtml(doc) {
|
|
|
7240
7434
|
text: runs,
|
|
7241
7435
|
position: { x: pxToInch(x), y: pxToInch(y), w: pxToInch(w), h: pxToInch(h) },
|
|
7242
7436
|
style: baseStyle,
|
|
7437
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
7243
7438
|
};
|
|
7244
7439
|
elements.push(textElement);
|
|
7245
7440
|
}
|
|
@@ -7257,6 +7452,7 @@ export function parseSlideHtml(doc) {
|
|
|
7257
7452
|
italic: computed.fontStyle === 'italic',
|
|
7258
7453
|
underline: computed.textDecoration.includes('underline'),
|
|
7259
7454
|
},
|
|
7455
|
+
zIndex: getEffectiveZIndex(el, win),
|
|
7260
7456
|
};
|
|
7261
7457
|
elements.push(textElement);
|
|
7262
7458
|
}
|
|
@@ -7298,11 +7494,18 @@ export function parseSlideHtml(doc) {
|
|
|
7298
7494
|
// PPTX renders shapes in XML order (later = on top), so we sort by z-index
|
|
7299
7495
|
// to ensure elements with higher z-index appear later in the array.
|
|
7300
7496
|
// Elements without z-index (undefined) are treated as z-index: 0.
|
|
7301
|
-
|
|
7302
|
-
|
|
7303
|
-
|
|
7304
|
-
|
|
7497
|
+
// When z-indexes are equal, preserve DOM order (original array order) as tiebreaker.
|
|
7498
|
+
const indexedElements = elements.map((el, i) => ({ el, originalIndex: i }));
|
|
7499
|
+
indexedElements.sort((a, b) => {
|
|
7500
|
+
const zIndexA = ('zIndex' in a.el && a.el.zIndex !== undefined) ? a.el.zIndex : 0;
|
|
7501
|
+
const zIndexB = ('zIndex' in b.el && b.el.zIndex !== undefined) ? b.el.zIndex : 0;
|
|
7502
|
+
if (zIndexA !== zIndexB) {
|
|
7503
|
+
return zIndexA - zIndexB;
|
|
7504
|
+
}
|
|
7505
|
+
// When z-indexes are equal, preserve DOM order
|
|
7506
|
+
return a.originalIndex - b.originalIndex;
|
|
7305
7507
|
});
|
|
7306
|
-
|
|
7508
|
+
const sortedElements = indexedElements.map(item => item.el);
|
|
7509
|
+
return { background, elements: sortedElements, placeholders, errors };
|
|
7307
7510
|
}
|
|
7308
7511
|
//# sourceMappingURL=parse.js.map
|