html2canvas-pro 2.3.7 → 2.3.9

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.7 <https://yorickshan.github.io/html2canvas-pro/>
2
+ * html2canvas-pro 2.3.9 <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,
@@ -10362,13 +10384,57 @@ function renderFormElements(ctx, textRenderer, pathFn, container, styles) {
10362
10384
  new Vector(bounds.left, bounds.top + bounds.height)
10363
10385
  ]);
10364
10386
  ctx.clip();
10365
- 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
+ });
10366
10404
  ctx.restore();
10367
10405
  ctx.textBaseline = "alphabetic";
10368
10406
  ctx.textAlign = "left";
10369
10407
  }
10370
10408
  }
10371
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
+ /**
10372
10438
  * Render list-item marker (image or text).
10373
10439
  */
10374
10440
  async function renderListMarker(ctx, context, textRenderer, paint, container, styles) {
@@ -10536,11 +10602,13 @@ var CanvasRenderer = class CanvasRenderer {
10536
10602
  }
10537
10603
  mask(paths) {
10538
10604
  this.ctx.beginPath();
10539
- this.ctx.moveTo(0, 0);
10540
- this.ctx.lineTo(this.options.width, 0);
10541
- this.ctx.lineTo(this.options.width, this.options.height);
10542
- this.ctx.lineTo(0, this.options.height);
10543
- this.ctx.lineTo(0, 0);
10605
+ const x = this.options.x;
10606
+ const y = this.options.y;
10607
+ this.ctx.moveTo(x, y);
10608
+ this.ctx.lineTo(x + this.options.width, y);
10609
+ this.ctx.lineTo(x + this.options.width, y + this.options.height);
10610
+ this.ctx.lineTo(x, y + this.options.height);
10611
+ this.ctx.lineTo(x, y);
10544
10612
  this.formatPath(paths.slice(0).reverse());
10545
10613
  this.ctx.closePath();
10546
10614
  }
@@ -10966,7 +11034,8 @@ var Cache = class {
10966
11034
  const originChecker = this.context.originChecker;
10967
11035
  const defaultIsSameOrigin = (src) => originChecker.isSameOrigin(src);
10968
11036
  const isSameOrigin = typeof this._options.customIsSameOrigin === "function" ? await this._options.customIsSameOrigin(key, defaultIsSameOrigin) : defaultIsSameOrigin(key);
10969
- const useCORS = !isInlineImage(key) && this._options.useCORS === true && FEATURES.SUPPORT_CORS_IMAGES && !isSameOrigin;
11037
+ const canAttemptCors = !isSameOrigin && this._options.allowTaint === false && !isInlineImage(key) && !isBlobImage(key) && typeof this._options.proxy !== "string";
11038
+ const useCORS = !isInlineImage(key) && (this._options.useCORS === true || canAttemptCors) && FEATURES.SUPPORT_CORS_IMAGES && !isSameOrigin;
10970
11039
  const useProxy = !isInlineImage(key) && !isSameOrigin && !isBlobImage(key) && typeof this._options.proxy === "string" && FEATURES.SUPPORT_CORS_XHR && !useCORS;
10971
11040
  if (!isSameOrigin && this._options.allowTaint === false && !isInlineImage(key) && !isBlobImage(key) && !useProxy && !useCORS) return;
10972
11041
  let src = key;