html2canvas-pro 2.3.5 → 2.3.6

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * html2canvas-pro 2.3.5 <https://yorickshan.github.io/html2canvas-pro/>
2
+ * html2canvas-pro 2.3.6 <https://yorickshan.github.io/html2canvas-pro/>
3
3
  * Copyright (c) 2024-present yorickshan and html2canvas-pro contributors
4
4
  * Released under MIT License
5
5
  */
@@ -7034,14 +7034,19 @@ var DocumentCloner = class {
7034
7034
  }
7035
7035
  if (clone.loading === "lazy") clone.loading = "eager";
7036
7036
  }
7037
- if (isCustomElement(clone) && !isSVGElementNode(clone)) return this.createCustomElementClone(clone);
7037
+ if (isCustomElement(clone) && !isSVGElementNode(clone)) return this.createCustomElementClone(node, clone);
7038
7038
  return clone;
7039
7039
  }
7040
- createCustomElementClone(node) {
7040
+ createCustomElementClone(originalNode, clonedNode) {
7041
7041
  const clone = document.createElement("div");
7042
- clone.className = node.className;
7043
- copyCSSStyles(node.style, clone);
7044
- if (node.shadowRoot) try {
7042
+ clone.className = clonedNode.className;
7043
+ copyCSSStyles(clonedNode.style, clone);
7044
+ const attributes = clonedNode.attributes;
7045
+ for (let i = 0; i < attributes.length; i++) {
7046
+ const attr = attributes[i];
7047
+ if (attr.name !== "class" && attr.name !== "style") clone.setAttribute(attr.name, attr.value);
7048
+ }
7049
+ if (originalNode.shadowRoot) try {
7045
7050
  clone.attachShadow({ mode: "open" });
7046
7051
  } catch (e) {
7047
7052
  this.context.logger.error("Failed to attach shadow root to custom element clone:", e);
@@ -7442,6 +7447,10 @@ var ElementContainer = class {
7442
7447
  this.originalElement = element;
7443
7448
  }
7444
7449
  this.bounds = parseBounds(this.context, element);
7450
+ if (element.tagName === "FIELDSET") {
7451
+ const legend = element.querySelector(":scope > legend");
7452
+ if (legend) this.legendBounds = parseBounds(this.context, legend);
7453
+ }
7445
7454
  if (isDebugging(element, 4)) this.debugRender = true;
7446
7455
  }
7447
7456
  /**
@@ -9078,6 +9087,7 @@ const measureBaseline = (ctx, fallback) => {
9078
9087
  //#endregion
9079
9088
  //#region src/render/canvas/text-renderer.ts
9080
9089
  const iOSBrokenFonts = ["-apple-system", "system-ui"];
9090
+ const TEXT_OVERFLOW_EPSILON = 1;
9081
9091
  /**
9082
9092
  * Detect CJK (Chinese, Japanese, Korean) characters in a string.
9083
9093
  * CJK characters use the ideographic baseline in browsers, which differs
@@ -9380,7 +9390,7 @@ var TextRenderer = class {
9380
9390
  const firstTop = text.textBounds[0].bounds.top;
9381
9391
  if (!text.textBounds.every((tb) => Math.abs(tb.bounds.top - firstTop) < lineHeight * .5)) return false;
9382
9392
  let fullText = text.textBounds.map((tb) => tb.text).join("").replace(/\s+/g, " ").trim();
9383
- if (this.ctx.measureText(fullText).width <= containerBounds.width) return false;
9393
+ if (this.ctx.measureText(fullText).width <= containerBounds.width + TEXT_OVERFLOW_EPSILON) return false;
9384
9394
  const bounds = new TextBounds(this.truncateTextWithEllipsis(fullText, containerBounds.width, styles.letterSpacing), text.textBounds[0].bounds);
9385
9395
  for (const layer of paintOrder) if (layer === 0) this.renderTextFillWithShadows(bounds, styles, baseline);
9386
9396
  else if (layer === 1) this.renderTextStrokeWithStyle(bounds, styles, baseline);
@@ -10618,10 +10628,38 @@ var CanvasRenderer = class CanvasRenderer {
10618
10628
  }
10619
10629
  let side = 0;
10620
10630
  for (const border of borders) {
10621
- if (border.style !== 0 && !isTransparent(border.color) && border.width > 0) if (border.style === 2) await this.borderRenderer.renderDashedDottedBorder(border.color, border.width, side, paint.curves, 2);
10622
- else if (border.style === 3) await this.borderRenderer.renderDashedDottedBorder(border.color, border.width, side, paint.curves, 3);
10623
- else if (border.style === 4) await this.borderRenderer.renderDoubleBorder(border.color, border.width, side, paint.curves);
10624
- else await this.borderRenderer.renderSolidBorder(border.color, side, paint.curves);
10631
+ if (border.style !== 0 && !isTransparent(border.color) && border.width > 0) {
10632
+ const renderBorderSide = async () => {
10633
+ if (border.style === 2) await this.borderRenderer.renderDashedDottedBorder(border.color, border.width, side, paint.curves, 2);
10634
+ else if (border.style === 3) await this.borderRenderer.renderDashedDottedBorder(border.color, border.width, side, paint.curves, 3);
10635
+ else if (border.style === 4) await this.borderRenderer.renderDoubleBorder(border.color, border.width, side, paint.curves);
10636
+ else await this.borderRenderer.renderSolidBorder(border.color, side, paint.curves);
10637
+ };
10638
+ const legend = paint.container.legendBounds;
10639
+ if (side === 0 && legend) {
10640
+ const bounds = paint.container.bounds;
10641
+ const legendLeft = legend.left - bounds.left;
10642
+ const legendRight = legend.left + legend.width - bounds.left;
10643
+ if (legendLeft > 0) {
10644
+ this.ctx.save();
10645
+ this.ctx.beginPath();
10646
+ this.ctx.rect(bounds.left, bounds.top, legendLeft, bounds.height);
10647
+ this.ctx.clip();
10648
+ await renderBorderSide();
10649
+ this.ctx.restore();
10650
+ }
10651
+ const rightStart = bounds.left + legendRight;
10652
+ const rightWidth = bounds.width - legendRight;
10653
+ if (rightWidth > 0) {
10654
+ this.ctx.save();
10655
+ this.ctx.beginPath();
10656
+ this.ctx.rect(rightStart, bounds.top, rightWidth, bounds.height);
10657
+ this.ctx.clip();
10658
+ await renderBorderSide();
10659
+ this.ctx.restore();
10660
+ }
10661
+ } else await renderBorderSide();
10662
+ }
10625
10663
  side++;
10626
10664
  }
10627
10665
  }