html2canvas-pro 2.3.6 → 2.3.8

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.6 <https://yorickshan.github.io/html2canvas-pro/>
2
+ * html2canvas-pro 2.3.8 <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
  */
@@ -5164,6 +5164,23 @@ const wordBreak = {
5164
5164
  }
5165
5165
  };
5166
5166
  //#endregion
5167
+ //#region src/css/property-descriptors/white-space.ts
5168
+ const whiteSpace = {
5169
+ name: "white-space",
5170
+ initialValue: "normal",
5171
+ prefix: false,
5172
+ type: 2,
5173
+ parse: (_context, value) => {
5174
+ switch (value) {
5175
+ case "pre": return "pre";
5176
+ case "nowrap": return "nowrap";
5177
+ case "pre-wrap": return "pre-wrap";
5178
+ case "pre-line": return "pre-line";
5179
+ default: return "normal";
5180
+ }
5181
+ }
5182
+ };
5183
+ //#endregion
5167
5184
  //#region src/css/property-descriptors/writing-mode.ts
5168
5185
  const isVerticalWritingMode = (writingMode) => writingMode !== 0;
5169
5186
  const isSidewaysWritingMode = (writingMode) => writingMode === 3 || writingMode === 4;
@@ -6604,6 +6621,11 @@ var CSSParsedDeclaration = class CSSParsedDeclaration {
6604
6621
  wordBreak,
6605
6622
  "wordBreak"
6606
6623
  ],
6624
+ [
6625
+ "whiteSpace",
6626
+ whiteSpace,
6627
+ "whiteSpace"
6628
+ ],
6607
6629
  [
6608
6630
  "writingMode",
6609
6631
  writingMode,
@@ -7449,7 +7471,12 @@ var ElementContainer = class {
7449
7471
  this.bounds = parseBounds(this.context, element);
7450
7472
  if (element.tagName === "FIELDSET") {
7451
7473
  const legend = element.querySelector(":scope > legend");
7452
- if (legend) this.legendBounds = parseBounds(this.context, legend);
7474
+ if (legend) {
7475
+ const legendBounds = parseBounds(this.context, legend);
7476
+ this.legendBounds = legendBounds;
7477
+ const borderBoxTop = legendBounds.top + legendBounds.height / 2 - this.styles.borderTopWidth / 2;
7478
+ this.bounds = new Bounds(this.bounds.left, borderBoxTop, this.bounds.width, this.bounds.height - (borderBoxTop - this.bounds.top));
7479
+ }
7453
7480
  }
7454
7481
  if (isDebugging(element, 4)) this.debugRender = true;
7455
7482
  }
@@ -10357,13 +10384,57 @@ function renderFormElements(ctx, textRenderer, pathFn, container, styles) {
10357
10384
  new Vector(bounds.left, bounds.top + bounds.height)
10358
10385
  ]);
10359
10386
  ctx.clip();
10360
- textRenderer.renderTextWithLetterSpacing(new TextBounds(container.value, textBounds), styles.letterSpacing, baseline, styles.writingMode);
10387
+ const lines = wrapTextToWidth(ctx, container.value, bounds.width, styles.whiteSpace === "pre" || styles.whiteSpace === "nowrap");
10388
+ const fontSizeValue = getAbsoluteValue(styles.fontSize, 0);
10389
+ const lineHeight = computeLineHeight(styles.lineHeight, fontSizeValue);
10390
+ lines.forEach((line, index) => {
10391
+ let lineX = textBounds.left;
10392
+ const lineWidth = ctx.measureText(line).width;
10393
+ switch (styles.textAlign) {
10394
+ case 1:
10395
+ lineX += (bounds.width - lineWidth) / 2;
10396
+ break;
10397
+ case 2:
10398
+ lineX += bounds.width - lineWidth;
10399
+ break;
10400
+ }
10401
+ const lineBounds = new Bounds(lineX, textBounds.top + index * lineHeight, 0, 0);
10402
+ textRenderer.renderTextWithLetterSpacing(new TextBounds(line, lineBounds), styles.letterSpacing, baseline, styles.writingMode);
10403
+ });
10361
10404
  ctx.restore();
10362
10405
  ctx.textBaseline = "alphabetic";
10363
10406
  ctx.textAlign = "left";
10364
10407
  }
10365
10408
  }
10366
10409
  /**
10410
+ * Split text into lines that fit the given pixel width, preserving hard line
10411
+ * breaks and (when wrapping is enabled) breaking at word boundaries — mirroring
10412
+ * how a <textarea> lays out its value.
10413
+ * @internal exported for testing
10414
+ */
10415
+ const wrapTextToWidth = (ctx, text, maxWidth, noWrap) => {
10416
+ const lines = [];
10417
+ const paragraphs = text.split("\n");
10418
+ for (const paragraph of paragraphs) {
10419
+ if (noWrap) {
10420
+ lines.push(paragraph);
10421
+ continue;
10422
+ }
10423
+ const words = paragraph.split(/(\s+)/);
10424
+ let line = "";
10425
+ for (const word of words) {
10426
+ const candidate = line + word;
10427
+ if (ctx.measureText(candidate).width <= maxWidth || line === "") line = candidate;
10428
+ else {
10429
+ lines.push(line);
10430
+ line = word;
10431
+ }
10432
+ }
10433
+ lines.push(line);
10434
+ }
10435
+ return lines;
10436
+ };
10437
+ /**
10367
10438
  * Render list-item marker (image or text).
10368
10439
  */
10369
10440
  async function renderListMarker(ctx, context, textRenderer, paint, container, styles) {
@@ -10961,7 +11032,8 @@ var Cache = class {
10961
11032
  const originChecker = this.context.originChecker;
10962
11033
  const defaultIsSameOrigin = (src) => originChecker.isSameOrigin(src);
10963
11034
  const isSameOrigin = typeof this._options.customIsSameOrigin === "function" ? await this._options.customIsSameOrigin(key, defaultIsSameOrigin) : defaultIsSameOrigin(key);
10964
- const useCORS = !isInlineImage(key) && this._options.useCORS === true && FEATURES.SUPPORT_CORS_IMAGES && !isSameOrigin;
11035
+ const canAttemptCors = !isSameOrigin && this._options.allowTaint === false && !isInlineImage(key) && !isBlobImage(key) && typeof this._options.proxy !== "string";
11036
+ const useCORS = !isInlineImage(key) && (this._options.useCORS === true || canAttemptCors) && FEATURES.SUPPORT_CORS_IMAGES && !isSameOrigin;
10965
11037
  const useProxy = !isInlineImage(key) && !isSameOrigin && !isBlobImage(key) && typeof this._options.proxy === "string" && FEATURES.SUPPORT_CORS_XHR && !useCORS;
10966
11038
  if (!isSameOrigin && this._options.allowTaint === false && !isInlineImage(key) && !isBlobImage(key) && !useProxy && !useCORS) return;
10967
11039
  let src = key;