diff --git a/src/components/src/plot-container.tsx b/src/components/src/plot-container.tsx index fe1444d30d..bf2ea08a7e 100644 --- a/src/components/src/plot-container.tsx +++ b/src/components/src/plot-container.tsx @@ -159,11 +159,12 @@ export default function PlotContainerFactory( _retrieveNewScreenshot = () => { if (this.plottingAreaRef.current) { - const {imageSize} = this.props.exportImageSetting; + const {imageSize, escapeXhtmlForWebpack} = this.props.exportImageSetting; convertToPng(this.plottingAreaRef.current, { filter: DOM_FILTER_FUNC, width: imageSize.imageW, - height: imageSize.imageH + height: imageSize.imageH, + escapeXhtmlForWebpack }) .then(this.props.setExportImageDataUri) .catch(err => { diff --git a/src/constants/src/default-settings.ts b/src/constants/src/default-settings.ts index e9b5e9a600..f59f7c494f 100644 --- a/src/constants/src/default-settings.ts +++ b/src/constants/src/default-settings.ts @@ -851,6 +851,7 @@ export type ExportImage = { exporting: boolean; processing: boolean; error: Error | false; + escapeXhtmlForWebpack?: boolean; // This field was not in the .d.ts file center: boolean; }; diff --git a/src/reducers/src/ui-state-updaters.ts b/src/reducers/src/ui-state-updaters.ts index 40d611a3d0..5745461c26 100644 --- a/src/reducers/src/ui-state-updaters.ts +++ b/src/reducers/src/ui-state-updaters.ts @@ -138,6 +138,7 @@ export const DEFAULT_MAP_CONTROLS: MapControls = (Object.keys(MAP_CONTROLS) as A * @property imageDataUri Default: `''`, * @property exporting Default: `false` * @property error Default: `false` + * @property escapeXhtmlForWebpack Default: `true` * @public */ export const DEFAULT_EXPORT_IMAGE: ExportImage = { @@ -161,7 +162,9 @@ export const DEFAULT_EXPORT_IMAGE: ExportImage = { exporting: false, // processing: used as loading indicator when export image is being produced processing: false, - error: false + error: false, + // whether to apply fix for uglify error in dom-to-image (should be true for webpack builds) + escapeXhtmlForWebpack: true }; export const DEFAULT_LOAD_FILES = { diff --git a/src/utils/src/dom-to-image.ts b/src/utils/src/dom-to-image.ts index 8fe4865223..70803404aa 100644 --- a/src/utils/src/dom-to-image.ts +++ b/src/utils/src/dom-to-image.ts @@ -75,20 +75,20 @@ const domtoimage = { }; /** - * @param {Node} node - The DOM Node object to render - * @param {Object} options - Rendering options - * @param {Function} [options.filter] - Should return true if passed node should be included in the output - * (excluding node means excluding it's children as well). Not called on the root node. - * @param {String} [options.bgcolor] - color for the background, any valid CSS color value. - * @param {Number} [options.width] - width to be applied to node before rendering. - * @param {Number} [options.height] - height to be applied to node before rendering. - * @param {Object} [options.style] - an object whose properties to be copied to node's style before rendering. - * @param {Number} [options.quality] - a Number between 0 and 1 indicating image quality (applicable to JPEG only), - defaults to 1.0. - * @param {String} [options.imagePlaceholder] - dataURL to use as a placeholder for failed images, default behaviour is to fail fast on images we can't fetch - * @param {Boolean} [options.cacheBust] - set to true to cache bust by appending the time to the request url - * @return {Promise} - A promise that is fulfilled with a SVG image data URL - * */ + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} [options.filter] - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well). Not called on the root node. + * @param {String} [options.bgcolor] - color for the background, any valid CSS color value. + * @param {Number} [options.width] - width to be applied to node before rendering. + * @param {Number} [options.height] - height to be applied to node before rendering. + * @param {Object} [options.style] - an object whose properties to be copied to node's style before rendering. + * @param {Number} [options.quality] - a Number between 0 and 1 indicating image quality (applicable to JPEG only), defaults to 1.0. + * @param {boolean} [options.escapeXhtmlForWebpack] - whether to apply fix for uglify error in dom-to-image (should be true for webpack builds), defaults to true. + * @param {String} [options.imagePlaceholder] - dataURL to use as a placeholder for failed images, default behaviour is to fail fast on images we can't fetch + * @param {Boolean} [options.cacheBust] - set to true to cache bust by appending the time to the request url + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ function toSvg(node, options) { options = options || {}; copyOptions(options); @@ -98,7 +98,12 @@ function toSvg(node, options) { .then(inlineImages) .then(applyOptions) .then(clone => - makeSvgDataUri(clone, options.width || getWidth(node), options.height || getHeight(node)) + makeSvgDataUri( + clone, + options.width || getWidth(node), + options.height || getHeight(node), + options.escapeXhtmlForWebpack + ) ); function applyOptions(clone) { @@ -249,12 +254,12 @@ function inlineImages(node) { return images.inlineAll(node).then(() => node); } -function makeSvgDataUri(node, width, height) { +function makeSvgDataUri(node, width, height, escapeXhtmlForWebpack = true) { return Promise.resolve(node).then(nd => { nd.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); const serializedString = new window.XMLSerializer().serializeToString(nd); - const xhtml = escapeXhtml(serializedString); + const xhtml = escapeXhtmlForWebpack ? escapeXhtml(serializedString) : serializedString; const foreignObject = `${xhtml}`; const svgStr = `${foreignObject}`;