docgen-utils 1.0.32 → 1.0.34

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.
@@ -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: extractZIndex(computed),
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: extractZIndex(computed),
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: extractZIndex(computed),
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
- elements.sort((a, b) => {
7302
- const zIndexA = ('zIndex' in a && a.zIndex !== undefined) ? a.zIndex : 0;
7303
- const zIndexB = ('zIndex' in b && b.zIndex !== undefined) ? b.zIndex : 0;
7304
- return zIndexA - zIndexB;
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
- return { background, elements, placeholders, errors };
7508
+ const sortedElements = indexedElements.map(item => item.el);
7509
+ return { background, elements: sortedElements, placeholders, errors };
7307
7510
  }
7308
7511
  //# sourceMappingURL=parse.js.map