docgen-utils 1.0.22 → 1.0.24

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 CHANGED
@@ -26853,6 +26853,7 @@ var docgen = (() => {
26853
26853
  exportPptx: () => exportPptx,
26854
26854
  importDocx: () => importDocx,
26855
26855
  importPptx: () => importPptx,
26856
+ parseSlideHtml: () => parseSlideHtml,
26856
26857
  transformHtmlForPptx: () => transformHtmlForPptx
26857
26858
  });
26858
26859
 
@@ -65552,6 +65553,31 @@ ${generateStylesCss(styleMap, themeFonts)}
65552
65553
  }
65553
65554
  return null;
65554
65555
  }
65556
+ function extractTranslation(computed) {
65557
+ const transform = computed.transform;
65558
+ if (!transform || transform === "none")
65559
+ return null;
65560
+ const matrix2dMatch = transform.match(/matrix\(([-\d.e]+),\s*([-\d.e]+),\s*([-\d.e]+),\s*([-\d.e]+),\s*([-\d.e]+),\s*([-\d.e]+)\)/);
65561
+ if (matrix2dMatch) {
65562
+ const tx = parseFloat(matrix2dMatch[5]);
65563
+ const ty = parseFloat(matrix2dMatch[6]);
65564
+ if (tx !== 0 || ty !== 0) {
65565
+ return { x: tx, y: ty };
65566
+ }
65567
+ }
65568
+ const matrix3dMatch = transform.match(/matrix3d\(([^)]+)\)/);
65569
+ if (matrix3dMatch) {
65570
+ const values = matrix3dMatch[1].split(",").map((v) => parseFloat(v.trim()));
65571
+ if (values.length >= 14) {
65572
+ const tx = values[12];
65573
+ const ty = values[13];
65574
+ if (tx !== 0 || ty !== 0) {
65575
+ return { x: tx, y: ty };
65576
+ }
65577
+ }
65578
+ }
65579
+ return null;
65580
+ }
65555
65581
  function getEffectiveOpacity(el, win) {
65556
65582
  let opacity = 1;
65557
65583
  let node = el;
@@ -66543,7 +66569,7 @@ ${generateStylesCss(styleMap, themeFonts)}
66543
66569
  pHeight = parentRect.height;
66544
66570
  }
66545
66571
  }
66546
- if (pWidth < 1 || pHeight < 1)
66572
+ if (pWidth < 0.5 || pHeight < 0.5)
66547
66573
  continue;
66548
66574
  let pLeft = parseFloat(pComputed.left);
66549
66575
  let pTop = parseFloat(pComputed.top);
@@ -66648,8 +66674,11 @@ ${generateStylesCss(styleMap, themeFonts)}
66648
66674
  borderOffsetLeft = parseFloat(parentComputedForBorder.borderLeftWidth) || 0;
66649
66675
  borderOffsetTop = parseFloat(parentComputedForBorder.borderTopWidth) || 0;
66650
66676
  }
66651
- const absLeft = parentRect.left + pLeft + borderOffsetLeft;
66652
- const absTop = parentRect.top + pTop + borderOffsetTop;
66677
+ const translation = extractTranslation(pComputed);
66678
+ const transformOffsetX = translation?.x ?? 0;
66679
+ const transformOffsetY = translation?.y ?? 0;
66680
+ const absLeft = parentRect.left + pLeft + borderOffsetLeft + transformOffsetX;
66681
+ const absTop = parentRect.top + pTop + borderOffsetTop + transformOffsetY;
66653
66682
  const hasBg = pComputed.backgroundColor && pComputed.backgroundColor !== "rgba(0, 0, 0, 0)";
66654
66683
  const bgImage = pComputed.backgroundImage;
66655
66684
  const hasGradient = bgImage && bgImage !== "none" && (bgImage.includes("linear-gradient") || bgImage.includes("radial-gradient"));
@@ -66854,7 +66883,18 @@ ${generateStylesCss(styleMap, themeFonts)}
66854
66883
  const transformStr = computed.textTransform;
66855
66884
  textTransform = (text) => applyTextTransform2(text, transformStr);
66856
66885
  }
66886
+ const runsBeforeRecurse = runs.length;
66887
+ const hadPendingSoftBreak = pendingSoftBreak;
66888
+ if (pendingSoftBreak) {
66889
+ pendingSoftBreak = false;
66890
+ }
66857
66891
  parseInlineFormatting(el, options, runs, textTransform, win);
66892
+ if (hadPendingSoftBreak && runs.length > runsBeforeRecurse) {
66893
+ runs[runsBeforeRecurse].options = {
66894
+ ...runs[runsBeforeRecurse].options,
66895
+ softBreakBefore: true
66896
+ };
66897
+ }
66858
66898
  }
66859
66899
  prevNodeIsText = false;
66860
66900
  }
@@ -67134,6 +67174,28 @@ ${generateStylesCss(styleMap, themeFonts)}
67134
67174
  const imgEl = el;
67135
67175
  const natW = imgEl.naturalWidth;
67136
67176
  const natH = imgEl.naturalHeight;
67177
+ let objectPosition;
67178
+ const objPos = imgComputed.objectPosition;
67179
+ if (objPos && objectFit === "cover") {
67180
+ const parts = objPos.trim().split(/\s+/);
67181
+ const parseFraction = (val, dimension) => {
67182
+ if (val.endsWith("%")) {
67183
+ return parseFloat(val) / 100;
67184
+ }
67185
+ const px = parseFloat(val);
67186
+ if (!isNaN(px) && dimension > 0) {
67187
+ return px / dimension;
67188
+ }
67189
+ return 0.5;
67190
+ };
67191
+ const displayW = wasClipped ? clippedW : rect2.width;
67192
+ const displayH = wasClipped ? clippedH : rect2.height;
67193
+ const xFrac = parts.length >= 1 ? parseFraction(parts[0], displayW) : 0.5;
67194
+ const yFrac = parts.length >= 2 ? parseFraction(parts[1], displayH) : xFrac;
67195
+ if (Math.abs(xFrac - 0.5) > 1e-3 || Math.abs(yFrac - 0.5) > 1e-3) {
67196
+ objectPosition = [xFrac, yFrac];
67197
+ }
67198
+ }
67137
67199
  const imageElement = {
67138
67200
  type: isFullSlideImage ? "slideBackgroundImage" : "image",
67139
67201
  src: imgSrc,
@@ -67145,10 +67207,13 @@ ${generateStylesCss(styleMap, themeFonts)}
67145
67207
  },
67146
67208
  sizing: objectFit === "cover" ? { type: "cover" } : null
67147
67209
  };
67148
- if (objectFit === "cover" && natW > 0 && natH > 0 && !isFullSlideImage) {
67210
+ if (objectFit === "cover" && natW > 0 && natH > 0) {
67149
67211
  imageElement.naturalWidth = natW;
67150
67212
  imageElement.naturalHeight = natH;
67151
67213
  }
67214
+ if (objectPosition) {
67215
+ imageElement.objectPosition = objectPosition;
67216
+ }
67152
67217
  if (imgRectRadius !== null) {
67153
67218
  imageElement.rectRadius = imgRectRadius;
67154
67219
  }
@@ -67576,8 +67641,21 @@ ${generateStylesCss(styleMap, themeFonts)}
67576
67641
  const textTagSet = /* @__PURE__ */ new Set(["P", "H1", "H2", "H3", "H4", "H5", "H6", "SPAN"]);
67577
67642
  const allChildren = Array.from(el.children);
67578
67643
  const textChildren = allChildren.filter((child) => {
67579
- if (textTagSet.has(child.tagName))
67644
+ if (textTagSet.has(child.tagName)) {
67645
+ if (child.tagName === "SPAN") {
67646
+ const spanComputed = win.getComputedStyle(child);
67647
+ const spanHasBg = spanComputed.backgroundColor && spanComputed.backgroundColor !== "rgba(0, 0, 0, 0)";
67648
+ const spanHasBorder = (parseFloat(spanComputed.borderTopWidth) || 0) > 0 || (parseFloat(spanComputed.borderRightWidth) || 0) > 0 || (parseFloat(spanComputed.borderBottomWidth) || 0) > 0 || (parseFloat(spanComputed.borderLeftWidth) || 0) > 0;
67649
+ const spanHasGradient = spanComputed.backgroundImage && spanComputed.backgroundImage !== "none" && (spanComputed.backgroundImage.includes("linear-gradient") || spanComputed.backgroundImage.includes("radial-gradient"));
67650
+ const spanBgClip = spanComputed.webkitBackgroundClip || spanComputed.backgroundClip;
67651
+ const spanTextFillColor = spanComputed.webkitTextFillColor;
67652
+ const isGradientText = spanBgClip === "text" && (spanTextFillColor === "transparent" || spanTextFillColor === "rgba(0, 0, 0, 0)" || spanTextFillColor && spanTextFillColor.includes("rgba") && spanTextFillColor.endsWith(", 0)"));
67653
+ if ((spanHasBg || spanHasBorder || spanHasGradient) && !isGradientText) {
67654
+ return false;
67655
+ }
67656
+ }
67580
67657
  return true;
67658
+ }
67581
67659
  if (child.tagName === "DIV") {
67582
67660
  const childComputed = win.getComputedStyle(child);
67583
67661
  const childDisplay = childComputed.display;
@@ -67678,7 +67756,9 @@ ${generateStylesCss(styleMap, themeFonts)}
67678
67756
  }
67679
67757
  }
67680
67758
  const hasDirectText = directTextContent.length > 0;
67681
- const shouldMergeText = hasTextChildren && (isSingleTextChild || nonTextChildren.length === 0) || hasDirectText;
67759
+ const isParentFlexRow = isFlexContainer2 && (computed2.flexDirection === "row" || computed2.flexDirection === "row-reverse" || !computed2.flexDirection) && allChildren.length > 1;
67760
+ const isParentGrid = display === "grid" || display === "inline-grid";
67761
+ const shouldMergeText = !isParentFlexRow && !isParentGrid && (hasTextChildren && (isSingleTextChild || nonTextChildren.length === 0) || hasDirectText);
67682
67762
  if (shouldMergeText) {
67683
67763
  if (isSingleTextChild) {
67684
67764
  const textEl = textChildren[0];
@@ -68055,10 +68135,34 @@ ${generateStylesCss(styleMap, themeFonts)}
68055
68135
  const plainDivChildCount = el.children.length;
68056
68136
  const isPlainDivFlexRow = (plainDivDisplay === "flex" || plainDivDisplay === "inline-flex") && (plainDivFlexDir === "row" || plainDivFlexDir === "row-reverse") && plainDivChildCount > 1;
68057
68137
  const isPlainDivGrid = plainDivDisplay === "grid" || plainDivDisplay === "inline-grid";
68058
- const allChildrenAreInlineText = !isPlainDivFlexRow && !isPlainDivGrid && (childElements.length === 0 || childElements.every((ce) => inlineTextTagsSet.has(ce.tagName.toUpperCase())));
68138
+ const isInlineTextChild = (ce) => {
68139
+ const tagName19 = ce.tagName.toUpperCase();
68140
+ if (!inlineTextTagsSet.has(tagName19))
68141
+ return false;
68142
+ if (tagName19 === "SPAN" || tagName19 === "A") {
68143
+ const ceComputed = win.getComputedStyle(ce);
68144
+ const ceHasBg = ceComputed.backgroundColor && ceComputed.backgroundColor !== "rgba(0, 0, 0, 0)";
68145
+ const ceHasBorder = (parseFloat(ceComputed.borderTopWidth) || 0) > 0 || (parseFloat(ceComputed.borderRightWidth) || 0) > 0 || (parseFloat(ceComputed.borderBottomWidth) || 0) > 0 || (parseFloat(ceComputed.borderLeftWidth) || 0) > 0;
68146
+ const ceHasGradient = ceComputed.backgroundImage && ceComputed.backgroundImage !== "none" && (ceComputed.backgroundImage.includes("linear-gradient") || ceComputed.backgroundImage.includes("radial-gradient"));
68147
+ const ceBgClip = ceComputed.webkitBackgroundClip || ceComputed.backgroundClip;
68148
+ const ceTextFillColor = ceComputed.webkitTextFillColor;
68149
+ const isGradientText = ceBgClip === "text" && (ceTextFillColor === "transparent" || ceTextFillColor === "rgba(0, 0, 0, 0)" || ceTextFillColor && ceTextFillColor.includes("rgba") && ceTextFillColor.endsWith(", 0)"));
68150
+ if ((ceHasBg || ceHasBorder || ceHasGradient) && !isGradientText) {
68151
+ return false;
68152
+ }
68153
+ }
68154
+ return true;
68155
+ };
68156
+ const allChildrenAreInlineText = !isPlainDivFlexRow && !isPlainDivGrid && (childElements.length === 0 || childElements.every((ce) => isInlineTextChild(ce)));
68059
68157
  const structuralChildElements = childElements.filter((ce) => {
68060
68158
  const tagName19 = ce.tagName.toUpperCase();
68061
- return tagName19 !== "BR" && tagName19 !== "SVG" && !inlineTextTagsSet.has(tagName19);
68159
+ if (tagName19 === "BR" || tagName19 === "SVG")
68160
+ return false;
68161
+ if (!inlineTextTagsSet.has(tagName19))
68162
+ return true;
68163
+ if (!isInlineTextChild(ce))
68164
+ return true;
68165
+ return false;
68062
68166
  });
68063
68167
  const hasStructuralChildren = structuralChildElements.length > 0;
68064
68168
  let extractedText = "";
@@ -68095,6 +68199,7 @@ ${generateStylesCss(styleMap, themeFonts)}
68095
68199
  const textTop = rect2.top;
68096
68200
  const textHeight = rect2.height;
68097
68201
  let textRuns;
68202
+ const isFlexColumn = (plainDivDisplay === "flex" || plainDivDisplay === "inline-flex") && (plainDivFlexDir === "column" || plainDivFlexDir === "column-reverse") && childElements.length > 1;
68098
68203
  if (allChildrenAreInlineText && childElements.length > 0) {
68099
68204
  const baseRunOptions = {
68100
68205
  fontSize: pxToPoints(computed22.fontSize),
@@ -68109,7 +68214,44 @@ ${generateStylesCss(styleMap, themeFonts)}
68109
68214
  if (computed22.textTransform && computed22.textTransform !== "none") {
68110
68215
  textTransformFn = (text2) => applyTextTransform2(text2, computed22.textTransform);
68111
68216
  }
68112
- textRuns = parseInlineFormatting(el, baseRunOptions, [], textTransformFn, win);
68217
+ if (isFlexColumn) {
68218
+ textRuns = [];
68219
+ for (let ci = 0; ci < childElements.length; ci++) {
68220
+ const childEl = childElements[ci];
68221
+ const childComputed = win.getComputedStyle(childEl);
68222
+ const childText = getTransformedText(childEl, childComputed);
68223
+ if (!childText)
68224
+ continue;
68225
+ const transformedChildText = textTransformFn(childText);
68226
+ const childRunOptions = { ...baseRunOptions };
68227
+ const childFontSize = pxToPoints(childComputed.fontSize);
68228
+ if (childFontSize)
68229
+ childRunOptions.fontSize = childFontSize;
68230
+ const childFontFace = extractFontFace(childComputed.fontFamily);
68231
+ if (childFontFace)
68232
+ childRunOptions.fontFace = childFontFace;
68233
+ const childColor = rgbToHex(childComputed.color);
68234
+ if (childColor)
68235
+ childRunOptions.color = childColor;
68236
+ if (parseInt(childComputed.fontWeight) >= 600) {
68237
+ childRunOptions.bold = true;
68238
+ } else if (parseInt(childComputed.fontWeight) < 600) {
68239
+ childRunOptions.bold = false;
68240
+ }
68241
+ if (childComputed.fontStyle === "italic") {
68242
+ childRunOptions.italic = true;
68243
+ } else if (childComputed.fontStyle !== "italic") {
68244
+ childRunOptions.italic = false;
68245
+ }
68246
+ const childLs = extractLetterSpacing(childComputed);
68247
+ if (childLs !== null)
68248
+ childRunOptions.charSpacing = childLs;
68249
+ const textWithBreak = ci < childElements.length - 1 ? transformedChildText + "\n" : transformedChildText;
68250
+ textRuns.push({ text: textWithBreak, options: childRunOptions });
68251
+ }
68252
+ } else {
68253
+ textRuns = parseInlineFormatting(el, baseRunOptions, [], textTransformFn, win);
68254
+ }
68113
68255
  if (textRuns.length === 0) {
68114
68256
  textRuns = [{ text: extractedText, options: {} }];
68115
68257
  }
@@ -68448,9 +68590,9 @@ ${generateStylesCss(styleMap, themeFonts)}
68448
68590
  elements.push(...pseudoElements);
68449
68591
  });
68450
68592
  doc.querySelectorAll("div").forEach((divEl) => {
68593
+ const htmlDiv = divEl;
68451
68594
  if (processed.has(divEl))
68452
68595
  return;
68453
- const htmlDiv = divEl;
68454
68596
  if (htmlDiv === body)
68455
68597
  return;
68456
68598
  const rect = htmlDiv.getBoundingClientRect();
@@ -68473,6 +68615,29 @@ ${generateStylesCss(styleMap, themeFonts)}
68473
68615
  }
68474
68616
  return runs;
68475
68617
  }
68618
+ function computeCoverCrop(naturalWidth, naturalHeight, boxW, boxH, objectPosition) {
68619
+ const imgRatio = naturalHeight / naturalWidth;
68620
+ const boxRatio = boxH / boxW;
68621
+ const isBoxBased = boxRatio > imgRatio;
68622
+ const effW = isBoxBased ? boxH / imgRatio : boxW;
68623
+ const effH = isBoxBased ? boxH : boxW * imgRatio;
68624
+ const [anchorX, anchorY] = objectPosition ?? [0.5, 0.5];
68625
+ const excessW = effW - boxW;
68626
+ const excessH = effH - boxH;
68627
+ const cropX = excessW * anchorX;
68628
+ const cropY = excessH * anchorY;
68629
+ return {
68630
+ effW,
68631
+ effH,
68632
+ sizing: {
68633
+ type: "crop",
68634
+ x: cropX,
68635
+ y: cropY,
68636
+ w: boxW,
68637
+ h: boxH
68638
+ }
68639
+ };
68640
+ }
68476
68641
  function sleep(ms) {
68477
68642
  return new Promise((resolve) => setTimeout(resolve, ms));
68478
68643
  }
@@ -68582,7 +68747,12 @@ ${generateStylesCss(styleMap, themeFonts)}
68582
68747
  w: el.position.w,
68583
68748
  h: el.position.h
68584
68749
  };
68585
- if (el.sizing && el.sizing.type) {
68750
+ if (el.sizing && el.sizing.type === "cover" && el.naturalWidth && el.naturalHeight) {
68751
+ const crop = computeCoverCrop(el.naturalWidth, el.naturalHeight, el.position.w, el.position.h, el.objectPosition);
68752
+ imageOptions.w = crop.effW;
68753
+ imageOptions.h = crop.effH;
68754
+ imageOptions.sizing = crop.sizing;
68755
+ } else if (el.sizing && el.sizing.type) {
68586
68756
  imageOptions.sizing = { type: el.sizing.type, w: el.position.w, h: el.position.h };
68587
68757
  }
68588
68758
  if (el.brightness !== void 0)
@@ -68624,22 +68794,10 @@ ${generateStylesCss(styleMap, themeFonts)}
68624
68794
  h: el.position.h
68625
68795
  };
68626
68796
  if (el.sizing && el.sizing.type === "cover" && el.naturalWidth && el.naturalHeight) {
68627
- const imgRatio = el.naturalHeight / el.naturalWidth;
68628
- const boxRatio = el.position.h / el.position.w;
68629
- const isBoxBased = boxRatio > imgRatio;
68630
- const effW = isBoxBased ? el.position.h / imgRatio : el.position.w;
68631
- const effH = isBoxBased ? el.position.h : el.position.w * imgRatio;
68632
- const cropX = (effW - el.position.w) / 2;
68633
- const cropY = (effH - el.position.h) / 2;
68634
- imageOptions.w = effW;
68635
- imageOptions.h = effH;
68636
- imageOptions.sizing = {
68637
- type: "crop",
68638
- x: cropX,
68639
- y: cropY,
68640
- w: el.position.w,
68641
- h: el.position.h
68642
- };
68797
+ const crop = computeCoverCrop(el.naturalWidth, el.naturalHeight, el.position.w, el.position.h, el.objectPosition);
68798
+ imageOptions.w = crop.effW;
68799
+ imageOptions.h = crop.effH;
68800
+ imageOptions.sizing = crop.sizing;
68643
68801
  } else if (el.sizing && el.sizing.type) {
68644
68802
  imageOptions.sizing = { type: el.sizing.type, w: el.position.w, h: el.position.h };
68645
68803
  }