html2canvas-pro 2.4.1 → 2.4.3

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.
@@ -9,10 +9,15 @@ exports.fontFamily = {
9
9
  parse: (_context, tokens) => {
10
10
  const accumulator = [];
11
11
  const results = [];
12
+ const quoted = [];
13
+ let isQuoted = false;
12
14
  tokens.forEach((token) => {
13
15
  switch (token.type) {
14
16
  case 20 /* TokenType.IDENT_TOKEN */:
17
+ accumulator.push(token.value);
18
+ break;
15
19
  case 0 /* TokenType.STRING_TOKEN */:
20
+ isQuoted = true;
16
21
  accumulator.push(token.value);
17
22
  break;
18
23
  case 17 /* TokenType.NUMBER_TOKEN */:
@@ -20,13 +25,23 @@ exports.fontFamily = {
20
25
  break;
21
26
  case 4 /* TokenType.COMMA_TOKEN */:
22
27
  results.push(accumulator.join(' '));
28
+ quoted.push(isQuoted);
29
+ isQuoted = false;
23
30
  accumulator.length = 0;
24
31
  break;
25
32
  }
26
33
  });
27
34
  if (accumulator.length) {
28
35
  results.push(accumulator.join(' '));
36
+ quoted.push(isQuoted);
29
37
  }
30
- return results.map((result) => (result.indexOf(' ') === -1 ? result : `'${result}'`));
38
+ return results.map((result, index) => quoted[index] || result.indexOf(' ') !== -1
39
+ ? `'${result
40
+ .replace(/\\/g, '\\\\')
41
+ .replace(/'/g, "\\'")
42
+ .replace(/\n/g, '\\a ')
43
+ .replace(/\r/g, '\\d ')
44
+ .replace(/\f/g, '\\c ')}'`
45
+ : result);
31
46
  }
32
47
  };
@@ -226,22 +226,27 @@ class BackgroundRenderer {
226
226
  if (rx > 0 && ry > 0) {
227
227
  // Cache key for radial gradient: position + radii + colour stops
228
228
  const cacheKey = `rg|${Math.round(x)}x${Math.round(y)}|${Math.round(rx)}x${Math.round(ry)}|${JSON.stringify(backgroundImage.stops)}`;
229
+ // The ellipse is rasterised as a circle of radius rx that is scaled vertically by
230
+ // ry / rx, so the offscreen canvas must be the ellipse's full bounding box
231
+ // (2rx × 2ry). Sizing it as a max(rx, ry) square stretched the gradient past the
232
+ // canvas edge whenever ry > rx, clipping the ellipse before its last stop and
233
+ // leaving a hard horizontal seam on tall elements.
234
+ const stops = (0, gradient_1.processColorStops)(backgroundImage.stops, rx * 2);
235
+ const lastStop = stops[stops.length - 1];
229
236
  let pattern = this.patternCache.get(cacheKey);
230
237
  if (!pattern) {
231
238
  const ownerDocument = this.canvas.ownerDocument ?? document;
232
- const size = Math.ceil(Math.max(rx, ry) * 2);
233
239
  const offscreen = ownerDocument.createElement('canvas');
234
- offscreen.width = size;
235
- offscreen.height = size;
240
+ offscreen.width = Math.ceil(rx * 2);
241
+ offscreen.height = Math.ceil(ry * 2);
236
242
  const offCtx = offscreen.getContext('2d');
237
243
  if (offCtx) {
238
- const offRadius = Math.max(rx, ry);
239
- const gradient = offCtx.createRadialGradient(offRadius, offRadius, 0, offRadius, offRadius, offRadius);
240
- (0, gradient_1.processColorStops)(backgroundImage.stops, offRadius * 2).forEach((s) => gradient.addColorStop(s.stop, (0, color_utilities_1.asString)(s.color)));
244
+ const gradient = offCtx.createRadialGradient(rx, rx, 0, rx, rx, rx);
245
+ stops.forEach((s) => gradient.addColorStop(s.stop, (0, color_utilities_1.asString)(s.color)));
241
246
  offCtx.fillStyle = gradient;
242
247
  if (rx !== ry)
243
248
  offCtx.scale(1, ry / rx);
244
- offCtx.fillRect(0, 0, offRadius * 2, offRadius * 2);
249
+ offCtx.fillRect(0, 0, rx * 2, rx * 2);
245
250
  pattern = this.ctx.createPattern(offscreen, 'no-repeat');
246
251
  this.patternCache.set(cacheKey, pattern);
247
252
  }
@@ -250,9 +255,15 @@ class BackgroundRenderer {
250
255
  this.path(path);
251
256
  this.ctx.save();
252
257
  this.ctx.clip();
253
- this.ctx.translate(left + x - Math.max(rx, ry), top + y - Math.max(rx, ry));
258
+ // Outside the ending shape a radial gradient continues with its last colour
259
+ // stop, so paint that first and lay the ellipse pattern on top.
260
+ if (lastStop) {
261
+ this.ctx.fillStyle = (0, color_utilities_1.asString)(lastStop.color);
262
+ this.ctx.fill();
263
+ }
264
+ this.ctx.translate(left + x - rx, top + y - ry);
254
265
  this.ctx.fillStyle = pattern;
255
- this.ctx.fillRect(0, 0, Math.max(rx, ry) * 2, Math.max(rx, ry) * 2);
266
+ this.ctx.fillRect(0, 0, rx * 2, ry * 2);
256
267
  this.ctx.restore();
257
268
  }
258
269
  }
package/package.json CHANGED
@@ -19,7 +19,7 @@
19
19
  "default": "./dist/html2canvas-pro.esm.js"
20
20
  }
21
21
  },
22
- "version": "2.4.1",
22
+ "version": "2.4.3",
23
23
  "author": {
24
24
  "name": "yorickshan",
25
25
  "email": "yorickshan@gmail.com",