UNPKG

@formio/core

Version:

The core Form.io renderering framework.

152 lines (151 loc) 5.94 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.uniqueName = exports.guid = exports.flattenComponents = exports.eachComponent = void 0; var Evaluator_1 = require("./Evaluator"); var lodash_1 = require("@formio/lodash"); /** * Iterate through each component within a form. * * @param {Object} components * The components to iterate. * @param {Function} fn * The iteration function to invoke for each component. * @param {Boolean} includeAll * Whether or not to include layout components. * @param {String} path * The current data path of the element. Example: data.user.firstName * @param {Object} parent * The parent object. */ function eachComponent(components, fn, includeAll, path, parent) { if (!components) return; path = path || ''; components.forEach(function (component) { if (!component) { return; } var hasColumns = component.columns && Array.isArray(component.columns); var hasRows = component.rows && Array.isArray(component.rows); var hasComps = component.components && Array.isArray(component.components); var noRecurse = false; var newPath = component.key ? (path ? ("".concat(path, ".").concat(component.key)) : component.key) : ''; // Keep track of parent references. if (parent) { // Ensure we don't create infinite JSON structures. component.parent = __assign({}, parent); delete component.parent.components; delete component.parent.componentMap; delete component.parent.columns; delete component.parent.rows; } // there's no need to add other layout components here because we expect that those would either have columns, rows or components var layoutTypes = ['htmlelement', 'content']; var isLayoutComponent = hasColumns || hasRows || hasComps || layoutTypes.indexOf(component.type) > -1; if (includeAll || component.tree || !isLayoutComponent) { noRecurse = fn(component, newPath, components); } var subPath = function () { if (component.key && !['panel', 'table', 'well', 'columns', 'fieldset', 'tabs', 'form'].includes(component.type) && (['datagrid', 'container', 'editgrid', 'address', 'dynamicWizard'].includes(component.type) || component.tree)) { return newPath; } else if (component.key && component.type === 'form') { return "".concat(newPath, ".data"); } return path; }; if (!noRecurse) { if (hasColumns) { component.columns.forEach(function (column) { return eachComponent(column.components, fn, includeAll, subPath(), parent ? component : null); }); } else if (hasRows) { component.rows.forEach(function (row) { if (Array.isArray(row)) { row.forEach(function (column) { return eachComponent(column.components, fn, includeAll, subPath(), parent ? component : null); }); } }); } else if (hasComps) { eachComponent(component.components, fn, includeAll, subPath(), parent ? component : null); } } }); } exports.eachComponent = eachComponent; /** * Flatten the form components for data manipulation. * * @param {Object} components * The components to iterate. * @param {Boolean} includeAll * Whether or not to include layout components. * * @returns {Object} * The flattened components map. */ function flattenComponents(components, includeAll) { var flattened = {}; eachComponent(components, function (component, path) { flattened[path] = component; }, includeAll); return flattened; } exports.flattenComponents = flattenComponents; function guid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0; var v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } exports.guid = guid; /** * Make a filename guaranteed to be unique. * @param name * @param template * @param evalContext * @returns {string} */ function uniqueName(name, template, evalContext) { template = template || '{{fileName}}-{{guid}}'; //include guid in template anyway, to prevent overwriting issue if filename matches existing file if (!template.includes('{{guid}}')) { template = "".concat(template, "-{{guid}}"); } var parts = name.split('.'); var fileName = parts.slice(0, parts.length - 1).join('.'); var extension = parts.length > 1 ? ".".concat((0, lodash_1.last)(parts)) : ''; //allow only 100 characters from original name to avoid issues with filename length restrictions fileName = fileName.substr(0, 100); evalContext = Object.assign(evalContext || {}, { fileName: fileName, guid: guid() }); //only letters, numbers, dots, dashes, underscores and spaces are allowed. Anything else will be replaced with dash var uniqueName = "".concat(Evaluator_1.Evaluator.interpolate(template, evalContext)).concat(extension).replace(/[^0-9a-zA-Z.\-_ ]/g, '-'); return uniqueName; } exports.uniqueName = uniqueName;