survey-pdf
Version:
Renders JSON-driven SurveyJS forms and their responses as PDF documents in the browser or Node.js: fillable interactive PDF forms (AcroForm) or static printouts.
156 lines (151 loc) • 7.24 kB
JavaScript
/*!
* surveyjs - SurveyJS PDF library v3.0.2
* Copyright (c) 2015-2026 Devsoft Baltic OÜ - http://surveyjs.io/
* License: MIT (http://www.opensource.org/licenses/mit-license.php)
*/
import { B as BaseImageUtils, r as rgbaToHex, a as registerImageUtils, b as registerVariablesManagerCreator } from './pdf-shared.mjs';
export { C as CheckItemBrick, c as CompositeBrick, d as CustomBrick, D as DocController, e as DocOptions, f as DrawCanvas, g as DropdownBrick, E as EmptyBrick, h as EventHandler, F as FlatBoolean, i as FlatCheckbox, j as FlatComment, k as FlatCustomModel, l as FlatDropdown, m as FlatExpression, n as FlatFile, o as FlatHTML, p as FlatImage, q as FlatImagePicker, s as FlatMatrix, t as FlatMatrixDynamic, u as FlatMatrixMultiple, v as FlatMultipleText, w as FlatPage, x as FlatPanel, y as FlatPanelDynamic, z as FlatQuestion, A as FlatQuestionDefault, G as FlatRadiogroup, H as FlatRanking, I as FlatRating, J as FlatRepository, K as FlatSelectBase, L as FlatSignaturePad, M as FlatSlider, N as FlatSurvey, O as FlatTextbox, P as HTMLBrick, Q as HorizontalAlign, R as ImageBrick, S as LinkBrick, T as PagePacker, U as PdfBrick, V as RadioItemBrick, W as RankingItemBrick, X as RowlineBrick, Y as SurveyHelper, Z as SurveyPDF, _ as TextBrick, $ as TextFieldBrick, a0 as VerticalAlign } from './pdf-shared.mjs';
import fetch from 'node-fetch';
import { imageSize } from 'image-size';
import { calcFromComponentValues } from '@csstools/css-calc';
import { color, serializeRGB } from '@csstools/css-color-parser';
import { parseListOfComponentValues, parseComponentValue, FunctionNode } from '@csstools/css-parser-algorithms';
import { tokenizer, stringify, tokenize } from '@csstools/css-tokenizer';
import 'survey-core';
import 'jspdf';
class ImageUtils extends BaseImageUtils {
async _getImageInfo(url) {
const pxToPt = 72.0 / 96.0;
let data;
if (typeof url === 'string' && url.startsWith('data:')) {
data = Buffer.from(url.split(',')[1] || '', 'base64');
}
else {
const res = await fetch(url);
data = new Uint8Array(await res.arrayBuffer());
}
const size = imageSize(data);
return { data: data, width: size.width * pxToPt, height: size.height * pxToPt, id: this.getImageId() };
}
}
class VariablesManager {
setup(variables) {
this.hash = {};
this.colorHash = {};
this.variables = variables;
}
tokenizeString(css) {
const t = tokenizer({ css });
const tokens = [];
while (!t.endOfFile()) {
tokens.push(t.nextToken());
}
tokens.push(t.nextToken());
return tokens;
}
splitComponentValuesByTopLevelComma(tokens) {
const parts = [];
let curr = [];
for (const tok of tokens) {
if (tok.type == 'token' && tok.value[0] == 'comma-token') {
parts.push(curr);
curr = [];
}
else {
curr.push(tok);
}
}
parts.push(curr);
return parts;
}
getVariable(name) {
if (!name)
return name;
if (!this.variables || !this.hash)
return undefined;
if (!this.variables[name])
return undefined;
if (this.hash[name])
return this.hash[name];
let value = this.variables[name];
const componentValues = parseListOfComponentValues(this.tokenizeString(value));
const replaceVars = (componentValues, depth = 0) => {
if (depth > 50)
return componentValues;
const out = [];
for (const componentValue of componentValues) {
if (componentValue.type === 'function') {
const functionComponentValue = componentValue;
const lowerName = (functionComponentValue.getName()).toLowerCase();
if (lowerName === 'var') {
const inner = functionComponentValue.value || [];
const parts = this.splitComponentValuesByTopLevelComma(inner);
const nameTokens = parts[0] || [];
const fallbackTokens = parts.length > 1 ? parts[1] : null;
const variableName = nameTokens.map((x) => stringify(...x.tokens())).join('').trim();
let replacementTokens = [];
const variableValue = this.getVariable(variableName);
if (!!variableValue) {
const componentValue = parseListOfComponentValues(this.tokenizeString(variableValue));
replacementTokens = componentValue;
}
else if (fallbackTokens && fallbackTokens.length > 0) {
replacementTokens = replaceVars(fallbackTokens, depth + 1);
}
else {
replacementTokens = [];
}
out.push(...replacementTokens);
continue;
}
else {
const inner = functionComponentValue.value || [];
const resolvedInner = replaceVars(inner, depth + 1);
out.push(new FunctionNode(functionComponentValue.name, functionComponentValue.endToken, resolvedInner));
continue;
}
}
else {
out.push(componentValue);
}
}
return out;
};
const replacedComponentValues = replaceVars(componentValues);
const processedValue = calcFromComponentValues([replacedComponentValues]).map(componentValues => componentValues.map((componentValue) => stringify(...componentValue.tokens())).join('')).join(',');
this.hash[name] = processedValue;
return processedValue;
}
getSizeVariable(name) {
const valueString = this.getVariable(name);
if (!valueString) {
return 0;
}
if (valueString.match(/px$/)) {
return Number.parseFloat(valueString) * 72.0 / 96.0;
}
else {
return Number.parseFloat(valueString);
}
}
getColorVariable(name) {
const valueString = this.getVariable(name);
if (!this.colorHash[valueString]) {
const hwbComponentValue = parseComponentValue(tokenize({ css: valueString }));
const colorData = color(hwbComponentValue);
if (colorData) {
const rgbComponentValue = serializeRGB(colorData);
this.colorHash[valueString] = rgbaToHex(rgbComponentValue.toString());
}
else {
this.colorHash[valueString] = '#000000';
}
}
return this.colorHash[valueString];
}
startCollectingVariables() { }
stopCollectingVariables() { }
}
registerImageUtils(new ImageUtils());
registerVariablesManagerCreator(() => new VariablesManager());
//# sourceMappingURL=survey.pdf.node.mjs.map