Files
metabase/patches/html2canvas-pro+2.0.2.patch
2026-07-17 11:08:38 -03:00

106 lines
5.0 KiB
Diff

diff --git a/node_modules/html2canvas-pro/dist/html2canvas-pro.esm.js b/node_modules/html2canvas-pro/dist/html2canvas-pro.esm.js
index d49f1bd..cb90b52 100644
--- a/node_modules/html2canvas-pro/dist/html2canvas-pro.esm.js
+++ b/node_modules/html2canvas-pro/dist/html2canvas-pro.esm.js
@@ -5875,6 +5875,8 @@ class SVGElementContainer extends ElementContainer {
constructor(context, img) {
super(context, img);
const s = new XMLSerializer();
+ // Remove transform to prevent double-application (transform is already accounted for in bounds/positioning)
+ img.style.transform = "none";
const bounds = parseBounds(context, img);
img.setAttribute('width', `${bounds.width}px`);
img.setAttribute('height', `${bounds.height}px`);
@@ -7144,14 +7146,55 @@ const ignoredStyleProperties = [
'd', // #2483
'content' // Safari shows pseudoelements if content is set
];
+const svgTextFontProperties = [
+ 'font-family',
+ 'font-size',
+ 'font-weight',
+ 'font-style',
+ 'font-variant',
+ 'font-stretch',
+ 'font-size-adjust',
+ 'letter-spacing',
+ 'word-spacing',
+ 'line-height',
+];
+const isSVGTextNode = (node) => {
+ const tagName = node.tagName;
+ return tagName === 'text' || tagName === 'tspan' || tagName === 'textPath';
+};
const copyCSSStyles = (style, target) => {
- // Edge does not provide value for cssText
- for (let i = style.length - 1; i >= 0; i--) {
- const property = style.item(i);
- // fix: Chrome_138 ignore custom properties
- if (ignoredStyleProperties.indexOf(property) === -1 && !property.startsWith('--')) {
- target.style.setProperty(property, style.getPropertyValue(property));
- }
+ // Use cssText for a single native call instead of iterating 300+ properties
+ // individually via style.item(i), which is extremely slow in Firefox due to
+ // Stylo's per-call indexmap lookups in the custom properties map.
+ target.style.cssText = style.cssText;
+ // Remove properties that should be ignored
+ for (let i = ignoredStyleProperties.length - 1; i >= 0; i--) {
+ target.style.removeProperty(ignoredStyleProperties[i]);
+ }
+ // For SVG text elements, explicitly re-apply font properties from the
+ // computed style since cssText may not reliably serialize them.
+ if (isSVGTextNode(target)) {
+ for (let i = 0; i < svgTextFontProperties.length; i++) {
+ const value = style.getPropertyValue(svgTextFontProperties[i]);
+ if (value) {
+ target.style.setProperty(svgTextFontProperties[i], value);
+ }
+ }
+ }
+ // cssText is empty for computed styles in Chrome, which drops the SVG's transform and
+ // offsets its serialized bounds, re-breaking #68751. Re-apply transform props explicitly.
+ const transform = style.getPropertyValue('transform');
+ if (transform && transform !== 'none') {
+ target.style.setProperty('transform', transform);
+ target.style.setProperty('transform-origin', style.getPropertyValue('transform-origin'));
+ target.style.setProperty('transform-box', style.getPropertyValue('transform-box'));
+ }
+ // Same empty-cssText Chrome quirk drops the resolved `color`, so SVGs painting
+ // with fill="currentColor" lose their inherited color when serialized standalone
+ // (rendered black). Re-apply it so currentColor resolves. (metabase#77001)
+ const color = style.getPropertyValue('color');
+ if (color) {
+ target.style.setProperty('color', color);
}
return target;
};
@@ -7534,7 +7577,8 @@ class ElementPaint {
const rotateMatrix = [cos, sin, -sin, cos, 0, 0];
this.effects.push(new TransformEffect(offsetX, offsetY, rotateMatrix));
}
- if (this.container.styles.transform !== null) {
+ // Skip TransformEffect for SVG elements - their transform is already baked into bounds
+ if (this.container.styles.transform !== null && !(this.container instanceof SVGElementContainer)) {
const origin = this.container.styles.transformOrigin;
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
const offsetY = this.container.bounds.top + getAbsoluteValue(origin[1], this.container.bounds.height);
@@ -10373,12 +10417,12 @@ class Validator {
}
// Basic format validation - nonce should be base64-like
// Typical format: base64 string, often 32+ characters
- if (nonce.length < 16) {
- return {
- valid: false,
- error: 'CSP nonce is too short (minimum 16 characters recommended)'
- };
- }
+ // if (nonce.length < 16) {
+ // return {
+ // valid: false,
+ // error: 'CSP nonce is too short (minimum 16 characters recommended)'
+ // };
+ // }
// Check for suspicious characters
if (!/^[A-Za-z0-9+/=_-]+$/.test(nonce)) {
return {