All files / src/web imageExport.ts

0% Statements 0/41
0% Branches 0/28
0% Functions 0/7
0% Lines 0/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84                                                                                                                                                                       
import * as vscode from 'vscode';
 
export interface ImageOverlayConfig {
	enabled: boolean;
	showProcessKey: boolean;
	showNamespace: boolean;
	showFilename: boolean;
	showDate: boolean;
	color: string;
	backgroundColor: string;
}
 
export function getImageExportConfig(): { enabled: boolean; format: string; overlay: ImageOverlayConfig } {
	const config = vscode.workspace.getConfiguration('flowableBpmnDesigner.imageExport');
	return {
		enabled: config.get<boolean>('enabled', false),
		format: config.get<string>('format', 'svg'),
		overlay: {
			enabled: config.get<boolean>('overlay.enabled', false),
			showProcessKey: config.get<boolean>('overlay.showProcessKey', true),
			showNamespace: config.get<boolean>('overlay.showNamespace', true),
			showFilename: config.get<boolean>('overlay.showFilename', true),
			showDate: config.get<boolean>('overlay.showDate', true),
			color: config.get<string>('overlay.color', '#999999'),
			backgroundColor: config.get<string>('overlay.backgroundColor', '#ffffff'),
		},
	};
}
 
function escapeXml(str: string, quoteDouble: boolean): string {
	let escaped = '';
	for (const char of str) {
		if (char === '&') {
			escaped += '&amp;';
			continue;
		}
		if (char === '<') {
			escaped += '&lt;';
			continue;
		}
		if (char === '>') {
			escaped += '&gt;';
			continue;
		}
		if (quoteDouble && char === '"') {
			escaped += '&quot;';
			continue;
		}
		escaped += char;
	}
	return escaped;
}
 
function escapeAttr(str: string): string {
	return escapeXml(str, true);
}
 
function escapeXmlText(str: string): string {
	return escapeXml(str, false);
}
 
export function addOverlayToSvg(svg: string, overlay: ImageOverlayConfig, processKey: string, targetNamespace: string, filename: string): string {
	if (!overlay.enabled) {
		return svg;
	}
 
	const lines: string[] = [];
	if (overlay.showProcessKey && processKey) { lines.push(`Key: ${processKey}`); }
	if (overlay.showNamespace && targetNamespace) { lines.push(`NS: ${targetNamespace}`); }
	if (overlay.showFilename && filename) { lines.push(`File: ${filename}`); }
	if (overlay.showDate) { lines.push(`Date: ${new Date().toISOString().split('T')[0]}`); }
	if (lines.length === 0) { return svg; }
 
	const lineHeight = 16;
	const padding = 8;
	const textWidth = Math.max(...lines.map((line) => line.length * 7)) + padding * 2;
	const textHeight = lines.length * lineHeight + padding * 2;
	const overlayGroup = `<g transform="translate(10, 10)">
<rect width="${textWidth}" height="${textHeight}" fill="${escapeAttr(overlay.backgroundColor)}" stroke="${escapeAttr(overlay.color)}" stroke-width="0.5" rx="3" opacity="0.9"/>
${lines.map((line, index) => `<text x="${padding}" y="${padding + (index + 1) * lineHeight - 3}" font-family="Arial, sans-serif" font-size="11" fill="${escapeAttr(overlay.color)}">${escapeXmlText(line)}</text>`).join('\n')}
</g>`;
 
	return svg.replace(/<\/svg>\s*$/, `${overlayGroup}\n</svg>`);
}