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