UNPKG

formiojs

Version:

Common js library for client side interaction with <form.io>

1,467 lines (1,198 loc) 128 kB
"use strict"; function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } require("core-js/modules/es.reflect.construct.js"); require("core-js/modules/es.reflect.get.js"); require("core-js/modules/es.object.get-own-property-descriptor.js"); require("core-js/modules/es.symbol.js"); require("core-js/modules/es.symbol.description.js"); require("core-js/modules/es.symbol.iterator.js"); require("core-js/modules/es.array.iterator.js"); require("core-js/modules/web.dom-collections.iterator.js"); require("core-js/modules/es.object.keys.js"); require("core-js/modules/es.object.get-own-property-descriptors.js"); require("core-js/modules/es.weak-map.js"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; require("core-js/modules/es.object.assign.js"); require("core-js/modules/es.function.name.js"); require("core-js/modules/es.regexp.flags.js"); require("core-js/modules/es.object.to-string.js"); require("core-js/modules/web.dom-collections.for-each.js"); require("core-js/modules/es.array.concat.js"); require("core-js/modules/es.array.includes.js"); require("core-js/modules/es.regexp.exec.js"); require("core-js/modules/es.string.split.js"); require("core-js/modules/es.string.includes.js"); require("core-js/modules/es.string.replace.js"); require("core-js/modules/es.string.starts-with.js"); require("core-js/modules/es.array.join.js"); require("core-js/modules/es.regexp.to-string.js"); require("core-js/modules/es.array.map.js"); require("core-js/modules/es.array.splice.js"); require("core-js/modules/es.array.filter.js"); require("core-js/modules/es.array.from.js"); require("core-js/modules/es.string.iterator.js"); require("core-js/modules/es.array.slice.js"); require("core-js/modules/es.object.get-prototype-of.js"); var _vanillaTextMask = require("@formio/vanilla-text-mask"); var _nativePromiseOnly = _interopRequireDefault(require("native-promise-only")); var _tippy = _interopRequireDefault(require("tippy.js")); var _lodash = _interopRequireDefault(require("lodash")); var _ismobilejs = _interopRequireDefault(require("ismobilejs")); var _Formio = require("../../../Formio"); var FormioUtils = _interopRequireWildcard(require("../../../utils/utils")); var _Validator = _interopRequireDefault(require("../../../validator/Validator")); var _Element2 = _interopRequireDefault(require("../../../Element")); var _ComponentModal = _interopRequireDefault(require("../componentModal/ComponentModal")); var _widgets = _interopRequireDefault(require("../../../widgets")); var _addons = _interopRequireDefault(require("../../../addons")); var _uploadAdapter = require("../../../providers/storage/uploadAdapter"); var _en = _interopRequireDefault(require("../../../translations/en")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(arguments.length < 3 ? target : receiver); } return desc.value; }; } return _get.apply(this, arguments); } function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } var isIEBrowser = FormioUtils.getBrowserInfo().ie; var CKEDITOR_URL = isIEBrowser ? 'https://cdn.ckeditor.com/4.14.1/standard/ckeditor.js' : 'https://cdn.form.io/ckeditor/19.0.0/ckeditor.js'; var QUILL_URL = isIEBrowser ? 'https://cdn.quilljs.com/1.3.7' : 'https://cdn.quilljs.com/2.0.0-dev.3'; var QUILL_TABLE_URL = 'https://cdn.form.io/quill/quill-table.js'; var ACE_URL = 'https://cdn.form.io/ace/1.4.10/ace.js'; var Templates = _Formio.GlobalFormio.Templates; if (!Templates) { Templates = require('../../../templates/Templates').default; } /** * This is the Component class which all elements within the FormioForm derive from. */ var Component = /*#__PURE__*/function (_Element) { _inherits(Component, _Element); var _super = _createSuper(Component); /* eslint-enable no-unused-vars */ /** * Initialize a new Component. * * @param {Object} component - The component JSON you wish to initialize. * @param {Object} options - The options for this component. * @param {Object} data - The global data submission object this component will belong. */ /* eslint-disable max-statements */ function Component(component, options, data) { var _this; _classCallCheck(this, Component); _this = _super.call(this, Object.assign({ renderMode: 'form', attachMode: 'full', noDefaults: false }, options || {})); // Restore the component id. if (component && component.id) { _this.id = component.id; } /** * Determines if this component has a condition assigned to it. * @type {null} * @private */ _this._hasCondition = null; /** * References to dom elements */ _this.refs = {}; // Allow global override for any component JSON. if (component && _this.options.components && _this.options.components[component.type]) { _lodash.default.merge(component, _this.options.components[component.type]); } /** * Set the validator instance. */ _this.validator = _Validator.default; /** * The data path to this specific component instance. * * @type {string} */ _this.path = ''; /** * The Form.io component JSON schema. * @type {*} */ _this.component = _this.mergeSchema(component || {}); // Add the id to the component. _this.component.id = _this.id; // Save off the original component to be used in logic. _this.originalComponent = (0, FormioUtils.fastCloneDeep)(_this.component); /** * If the component has been attached */ _this.attached = false; /** * If the component has been rendered */ _this.rendered = false; /** * The data object in which this component resides. * @type {*} */ _this._data = data || {}; /** * The existing error that this component has. * @type {string} */ _this.error = ''; /** * Tool tip text after processing * @type {string} */ _this.tooltip = ''; /** * The row path of this component. * @type {number} */ _this.row = _this.options.row; /** * Determines if this component is disabled, or not. * * @type {boolean} */ _this._disabled = (0, FormioUtils.boolValue)(_this.component.disabled) ? _this.component.disabled : false; /** * Points to the root component, usually the FormComponent. * * @type {Component} */ _this.root = _this.options.root; _this.localRoot = _this.options.localRoot; /** * If this input has been input and provided value. * * @type {boolean} */ _this.pristine = true; /** * Points to the parent component. * * @type {Component} */ _this.parent = _this.options.parent; _this.options.name = _this.options.name || 'data'; /** * The validators that are assigned to this component. * @type {[string]} */ _this.validators = ['required', 'minLength', 'maxLength', 'minWords', 'maxWords', 'custom', 'pattern', 'json', 'mask']; _this._path = ''; // Nested forms don't have parents so we need to pass their path in. _this._parentPath = _this.options.parentPath || ''; // Needs for Nextgen Rules Engine _this.resetCaches(); /** * Determines if this component is visible, or not. */ _this._parentVisible = _this.options.hasOwnProperty('parentVisible') ? _this.options.parentVisible : true; _this._visible = _this._parentVisible && _this.conditionallyVisible(null, data); _this._parentDisabled = false; /** * Used to trigger a new change in this component. * @type {function} - Call to trigger a change in this component. */ var changes = []; var lastChanged = null; var triggerArgs = []; var _triggerChange = _lodash.default.debounce(function () { var _this2; if (_this.root) { _this.root.changing = false; } triggerArgs = []; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } if (!args[1] && lastChanged) { // Set the changed component if one isn't provided. args[1] = lastChanged; } if (_lodash.default.isEmpty(args[0]) && lastChanged) { // Set the flags if it is empty and lastChanged exists. args[0] = lastChanged.flags; } lastChanged = null; args[3] = changes; var retVal = (_this2 = _this).onChange.apply(_this2, args); changes = []; return retVal; }, 100); _this.triggerChange = function () { for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } if (args[1]) { // Make sure that during the debounce that we always track lastChanged component, even if they // don't provide one later. lastChanged = args[1]; changes.push(lastChanged); } if (_this.root) { _this.root.changing = true; } if (args.length) { triggerArgs = args; } return _triggerChange.apply(void 0, _toConsumableArray(triggerArgs)); }; /** * Used to trigger a redraw event within this component. * * @type {Function} */ _this.triggerRedraw = _lodash.default.debounce(_this.redraw.bind(_assertThisInitialized(_this)), 100); /** * list of attached tooltips * @type {Array} */ _this.tooltips = []; /** * List of attached addons * @type {Array} */ _this.addons = []; // To force this component to be invalid. _this.invalid = false; if (_this.component) { _this.type = _this.component.type; if (_this.allowData && _this.key) { _this.options.name += "[".concat(_this.key, "]"); // If component is visible or not set to clear on hide, set the default value. if (_this.visible || !_this.component.clearOnHide) { if (!_this.hasValue()) { if (_this.shouldAddDefaultValue) { _this.dataValue = _this.defaultValue; } } else { // Ensure the dataValue is set. /* eslint-disable no-self-assign */ _this.dataValue = _this.dataValue; /* eslint-enable no-self-assign */ } } } /** * The element information for creating the input element. * @type {*} */ _this.info = _this.elementInfo(); } // Allow anyone to hook into the component creation. _this.hook('component'); if (!_this.options.skipInit) { _this.init(); } return _this; } /* eslint-enable max-statements */ _createClass(Component, [{ key: "data", get: function get() { return this._data; }, set: function set(value) { this._data = value; } }, { key: "mergeSchema", value: function mergeSchema() { var component = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return _lodash.default.defaultsDeep(component, this.defaultSchema); } // Allow componets to notify when ready. }, { key: "ready", get: function get() { return _nativePromiseOnly.default.resolve(this); } }, { key: "labelInfo", get: function get() { var label = {}; label.hidden = this.labelIsHidden(); label.className = ''; label.labelPosition = this.component.labelPosition; label.tooltipClass = "".concat(this.iconClass('question-sign'), " text-muted"); var isPDFReadOnlyMode = this.parent && this.parent.form && this.parent.form.display === 'pdf' && this.options.readOnly; if (this.hasInput && this.component.validate && (0, FormioUtils.boolValue)(this.component.validate.required) && !isPDFReadOnlyMode) { label.className += ' field-required'; } if (label.hidden) { label.className += ' control-label--hidden'; } if (this.info.attr.id) { label.for = this.info.attr.id; } return label; } }, { key: "init", value: function init() { var _this$component$addon, _this3 = this; this.disabled = this.shouldDisabled; this._visible = this.conditionallyVisible(null, null); if ((_this$component$addon = this.component.addons) !== null && _this$component$addon !== void 0 && _this$component$addon.length) { this.component.addons.forEach(function (addon) { return _this3.createAddon(addon); }); } } }, { key: "createAddon", value: function createAddon(addonConfiguration) { var _addonConfiguration$s; var name = addonConfiguration.name; if (!name) { return; } var settings = ((_addonConfiguration$s = addonConfiguration.settings) === null || _addonConfiguration$s === void 0 ? void 0 : _addonConfiguration$s.data) || {}; var Addon = _addons.default[name]; var addon = null; if (Addon) { var supportedComponents = Addon.info.supportedComponents; var supportsThisComponentType = !(supportedComponents !== null && supportedComponents !== void 0 && supportedComponents.length) || supportedComponents.indexOf(this.component.type) !== -1; if (supportsThisComponentType) { addon = new Addon(settings, this); this.addons.push(addon); } else { console.warn("Addon ".concat(name, " does not support component of type ").concat(this.component.type, ".")); } } return addon; } }, { key: "destroy", value: function destroy() { _get(_getPrototypeOf(Component.prototype), "destroy", this).call(this); this.detach(); this.addons.forEach(function (addon) { return addon.destroy(); }); } }, { key: "shouldDisabled", get: function get() { return this.options.readOnly || this.component.disabled || this.options.hasOwnProperty('disabled') && this.options.disabled[this.key]; } }, { key: "isInputComponent", get: function get() { return !this.component.hasOwnProperty('input') || this.component.input; } }, { key: "allowData", get: function get() { return this.hasInput; } }, { key: "hasInput", get: function get() { return this.isInputComponent || this.refs.input && this.refs.input.length; } }, { key: "defaultSchema", get: function get() { return Component.schema(); } }, { key: "key", get: function get() { return _lodash.default.get(this.component, 'key', ''); } }, { key: "parentVisible", get: function get() { return this._parentVisible; }, set: function set(value) { this._parentVisible = value; } }, { key: "parentDisabled", get: function get() { return this._parentDisabled; } /** * * @param value {boolean} */ , set: function set(value) { this._parentDisabled = value; } }, { key: "visible", get: /** * * @returns {boolean} */ function get() { // Show only if visibility changes or if we are in builder mode or if hidden fields should be shown. if (this.builderMode || this.previewMode || this.options.showHiddenFields) { return true; } if (this.options.hide && this.options.hide[this.component.key]) { return false; } if (this.options.show && this.options.show[this.component.key]) { return true; } return this._visible && this._parentVisible; }, set: function set(value) { if (this._visible !== value) { this._visible = value; this.clearOnHide(); this.redraw(); } } }, { key: "currentForm", get: function get() { return this._currentForm; }, set: function set(instance) { this._currentForm = instance; } }, { key: "fullMode", get: function get() { return this.options.attachMode === 'full'; } }, { key: "builderMode", get: function get() { return this.options.attachMode === 'builder'; } }, { key: "calculatedPath", get: function get() { console.error('component.calculatedPath was deprecated, use component.path instead.'); return this.path; } }, { key: "labelPosition", get: function get() { return this.component.labelPosition; } }, { key: "labelWidth", get: function get() { var width = this.component.labelWidth; return width >= 0 ? width : 30; } }, { key: "labelMargin", get: function get() { var margin = this.component.labelMargin; return margin >= 0 ? margin : 3; } }, { key: "isAdvancedLabel", get: function get() { return ['left-left', 'left-right', 'right-left', 'right-right'].includes(this.labelPosition); } }, { key: "labelPositions", get: function get() { return this.labelPosition.split('-'); } }, { key: "skipInEmail", get: function get() { return false; } }, { key: "rightDirection", value: function rightDirection(direction) { return direction === 'right'; } }, { key: "getLabelInfo", value: function getLabelInfo() { var isRightPosition = this.rightDirection(this.labelPositions[0]); var isLeftPosition = this.labelPositions[0] === 'left'; var isRightAlign = this.rightDirection(this.labelPositions[1]); var contentMargin = ''; if (this.component.hideLabel) { var margin = this.labelWidth + this.labelMargin; contentMargin = isRightPosition ? "margin-right: ".concat(margin, "%") : ''; contentMargin = isLeftPosition ? "margin-left: ".concat(margin, "%") : ''; } var labelStyles = "\n flex: ".concat(this.labelWidth, ";\n ").concat(isRightPosition ? 'margin-left' : 'margin-right', ": ").concat(this.labelMargin, "%;\n "); var contentStyles = "\n flex: ".concat(100 - this.labelWidth - this.labelMargin, ";\n ").concat(contentMargin, ";\n ").concat(this.component.hideLabel ? "max-width: ".concat(100 - this.labelWidth - this.labelMargin) : '', ";\n "); return { isRightPosition: isRightPosition, isRightAlign: isRightAlign, labelStyles: labelStyles, contentStyles: contentStyles }; } /** * Returns only the schema that is different from the default. * * @param schema * @param defaultSchema */ }, { key: "getModifiedSchema", value: function getModifiedSchema(schema, defaultSchema, recursion) { var _this4 = this; var modified = {}; if (!defaultSchema) { return schema; } _lodash.default.each(schema, function (val, key) { if (!_lodash.default.isArray(val) && _lodash.default.isObject(val) && defaultSchema.hasOwnProperty(key)) { var subModified = _this4.getModifiedSchema(val, defaultSchema[key], true); if (!_lodash.default.isEmpty(subModified)) { modified[key] = subModified; } } else if (_lodash.default.isArray(val)) { if (val.length !== 0 && !_lodash.default.isEqual(val, defaultSchema[key])) { modified[key] = val; } } else if (!recursion && key === 'type' || !recursion && key === 'key' || !recursion && key === 'label' || !recursion && key === 'input' || !recursion && key === 'tableView' || val !== '' && !defaultSchema.hasOwnProperty(key) || val !== '' && val !== defaultSchema[key] || defaultSchema[key] && val !== defaultSchema[key]) { modified[key] = val; } }); return modified; } /** * Returns the JSON schema for this component. */ }, { key: "schema", get: function get() { return (0, FormioUtils.fastCloneDeep)(this.getModifiedSchema(_lodash.default.omit(this.component, 'id'), this.defaultSchema)); } /** * Returns true if component is inside DataGrid */ }, { key: "isInDataGrid", get: function get() { return this.inDataGrid; } /** * Translate a text using the i18n system. * * @param {string} text - The i18n identifier. * @param {Object} params - The i18n parameters to use for translation. */ }, { key: "t", value: function t(text) { var _get2; var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (!text) { return ''; } // Use _userInput: true to ignore translations from defaults if (text in _en.default && params._userInput) { return text; } params.data = this.rootValue; params.row = this.data; params.component = this.component; for (var _len3 = arguments.length, args = new Array(_len3 > 2 ? _len3 - 2 : 0), _key3 = 2; _key3 < _len3; _key3++) { args[_key3 - 2] = arguments[_key3]; } return (_get2 = _get(_getPrototypeOf(Component.prototype), "t", this)).call.apply(_get2, [this, text, params].concat(args)); } }, { key: "labelIsHidden", value: function labelIsHidden() { return !this.component.label || (!this.isInDataGrid && this.component.hideLabel || this.isInDataGrid && !this.component.dataGridLabel || this.options.inputsOnly) && !this.builderMode; } }, { key: "transform", get: function get() { return Templates.current.hasOwnProperty('transform') ? Templates.current.transform.bind(Templates.current) : function (type, value) { return value; }; } }, { key: "getTemplate", value: function getTemplate(names, modes) { modes = Array.isArray(modes) ? modes : [modes]; names = Array.isArray(names) ? names : [names]; if (!modes.includes('form')) { modes.push('form'); } var result = null; if (this.options.templates) { result = this.checkTemplate(this.options.templates, names, modes); if (result) { return result; } } var frameworkTemplates = this.options.template ? Templates.templates[this.options.template] : Templates.current; result = this.checkTemplate(frameworkTemplates, names, modes); if (result) { return result; } // Default back to bootstrap if not defined. var name = names[names.length - 1]; var templatesByName = Templates.defaultTemplates[name]; if (!templatesByName) { return "Unknown template: ".concat(name); } var templateByMode = this.checkTemplateMode(templatesByName, modes); if (templateByMode) { return templateByMode; } return templatesByName.form; } }, { key: "checkTemplate", value: function checkTemplate(templates, names, modes) { var _iterator = _createForOfIteratorHelper(names), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var name = _step.value; var templatesByName = templates[name]; if (templatesByName) { var templateByMode = this.checkTemplateMode(templatesByName, modes); if (templateByMode) { return templateByMode; } } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return null; } }, { key: "checkTemplateMode", value: function checkTemplateMode(templatesByName, modes) { var _iterator2 = _createForOfIteratorHelper(modes), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var mode = _step2.value; var templateByMode = templatesByName[mode]; if (templateByMode) { return templateByMode; } } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } return null; } }, { key: "getFormattedTooltip", value: function getFormattedTooltip(tooltipValue) { var tooltip = this.interpolate(tooltipValue || '').replace(/(?:\r\n|\r|\n)/g, '<br />'); return tooltip ? this.t(tooltip, { _userInput: true }).replace(/"/g, '&quot;') : ''; } }, { key: "isHtmlRenderMode", value: function isHtmlRenderMode() { return this.options.renderMode === 'html'; } }, { key: "renderTemplate", value: function renderTemplate(name) { var _this5 = this; var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var modeOption = arguments.length > 2 ? arguments[2] : undefined; // Need to make this fall back to form if renderMode is not found similar to how we search templates. var mode = modeOption || this.options.renderMode || 'form'; data.component = this.component; data.self = this; data.options = this.options; data.readOnly = this.options.readOnly; data.iconClass = this.iconClass.bind(this); data.size = this.size.bind(this); data.t = this.t.bind(this); data.transform = this.transform; data.id = data.id || this.id; data.key = data.key || this.key; data.value = data.value || this.dataValue; data.disabled = this.disabled; data.builder = this.builderMode; data.render = function () { console.warn("Form.io 'render' template function is deprecated.\n If you need to render template (template A) inside of another template (template B),\n pass pre-compiled template A (use this.renderTemplate('template_A_name') as template context variable for template B"); return _this5.renderTemplate.apply(_this5, arguments); }; data.label = this.labelInfo; data.tooltip = this.getFormattedTooltip(this.component.tooltip); // Allow more specific template names var names = ["".concat(name, "-").concat(this.component.type, "-").concat(this.key), "".concat(name, "-").concat(this.component.type), "".concat(name, "-").concat(this.key), "".concat(name)]; // Allow template alters. return this.hook("render".concat(name.charAt(0).toUpperCase() + name.substring(1, name.length)), this.interpolate(this.getTemplate(names, mode), data), data, mode); } /** * Sanitize an html string. * * @param string * @returns {*} */ }, { key: "sanitize", value: function sanitize(dirty, forceSanitize, options) { var _this$options; // No need to sanitize when generating PDF'S since no users interact with the form. if (!this.shouldSanitizeValue && !forceSanitize || this.options.pdf && !forceSanitize) { return dirty; } return FormioUtils.sanitize(dirty, { sanitizeConfig: _lodash.default.merge(((_this$options = this.options) === null || _this$options === void 0 ? void 0 : _this$options.sanitizeConfig) || {}, options || {}) }); } /** * Render a template string into html. * * @param template * @param data * @param actions * * @return {HTMLElement|String} - The created element or an empty string if template is not specified. */ }, { key: "renderString", value: function renderString(template, data) { if (!template) { return ''; } // Interpolate the template and populate return this.interpolate(template, data); } }, { key: "performInputMapping", value: function performInputMapping(input) { return input; } }, { key: "widget", get: function get() { var _this$root; var settings = this.component.widget; if (settings && (_this$root = this.root) !== null && _this$root !== void 0 && _this$root.shadowRoot) { settings.shadowRoot = this.root.shadowRoot; } var widget = settings && _widgets.default[settings.type] ? new _widgets.default[settings.type](settings, this.component, this) : null; return widget; } }, { key: "getBrowserLanguage", value: function getBrowserLanguage() { var nav = window.navigator; var browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage']; var language; // support for HTML 5.1 "navigator.languages" if (Array.isArray(nav.languages)) { for (var i = 0; i < nav.languages.length; i++) { language = nav.languages[i]; if (language && language.length) { return language.split(';')[0]; } } } // support for other well known properties in browsers for (var _i = 0; _i < browserLanguagePropertyKeys.length; _i++) { language = nav[browserLanguagePropertyKeys[_i]]; if (language && language.length) { return language.split(';')[0]; } } return null; } /** * Called before a next and previous page is triggered allowing the components * to perform special functions. * * @return {*} */ }, { key: "beforePage", value: function beforePage() { return _nativePromiseOnly.default.resolve(true); } }, { key: "beforeNext", value: function beforeNext() { return this.beforePage(true); } /** * Called before a submission is triggered allowing the components * to perform special async functions. * * @return {*} */ }, { key: "beforeSubmit", value: function beforeSubmit() { return _nativePromiseOnly.default.resolve(true); } /** * Return the submission timezone. * * @return {*} */ }, { key: "submissionTimezone", get: function get() { this.options.submissionTimezone = this.options.submissionTimezone || _lodash.default.get(this.root, 'options.submissionTimezone'); return this.options.submissionTimezone; } }, { key: "loadRefs", value: function loadRefs(element, refs) { for (var ref in refs) { var refType = refs[ref]; var isString = typeof refType === 'string'; var selector = isString && refType.includes('scope') ? ":scope > [ref=\"".concat(ref, "\"]") : "[ref=\"".concat(ref, "\"]"); if (isString && refType.startsWith('single')) { this.refs[ref] = element.querySelector(selector); } else { this.refs[ref] = element.querySelectorAll(selector); } } } }, { key: "setOpenModalElement", value: function setOpenModalElement(template) { this.componentModal.setOpenModalElement(template || this.getModalPreviewTemplate()); } }, { key: "getModalPreviewTemplate", value: function getModalPreviewTemplate() { var dataValue = this.component.type === 'password' ? this.dataValue.replace(/./g, '•') : this.dataValue; var message = this.error ? { level: 'error', message: this.error.message } : ''; return this.renderTemplate('modalPreview', { previewText: this.getValueAsString(dataValue, { modalPreview: true }) || this.t('Click to set value'), messages: message && this.renderTemplate('message', message) }); } }, { key: "build", value: function build(element) { element = element || this.element; this.empty(element); this.setContent(element, this.render()); return this.attach(element); } }, { key: "hasModalSaveButton", get: function get() { return true; } }, { key: "render", value: function render() { var children = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "Unknown component: ".concat(this.component.type); var topLevel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var isVisible = this.visible; this.rendered = true; if (!this.builderMode && !this.previewMode && this.component.modalEdit) { return _ComponentModal.default.render(this, { visible: isVisible, showSaveButton: this.hasModalSaveButton, id: this.id, classes: this.className, styles: this.customStyle, children: children }, topLevel); } else { return this.renderTemplate('component', { visible: isVisible, id: this.id, classes: this.className, styles: this.customStyle, children: children }, topLevel); } } }, { key: "attachTooltips", value: function attachTooltips(toolTipsRefs) { var _this6 = this; toolTipsRefs === null || toolTipsRefs === void 0 ? void 0 : toolTipsRefs.forEach(function (tooltip, index) { if (tooltip) { var tooltipAttribute = tooltip.getAttribute('data-tooltip'); var tooltipDataTitle = tooltip.getAttribute('data-title'); var tooltipText = _this6.interpolate(tooltipDataTitle || tooltipAttribute).replace(/(?:\r\n|\r|\n)/g, '<br />'); _this6.tooltips[index] = (0, _tippy.default)(tooltip, { allowHTML: true, trigger: 'mouseenter click focus', placement: 'right', zIndex: 10000, interactive: true, content: _this6.t(tooltipText, { _userInput: true }) }); } }); } }, { key: "createComponentModal", value: function createComponentModal(element, modalShouldBeOpened, currentValue) { return new _ComponentModal.default(this, element, modalShouldBeOpened, currentValue); } }, { key: "attach", value: function attach(element) { if (!this.builderMode && !this.previewMode && this.component.modalEdit) { var modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false; var currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue; var openModalTemplate = this.componentModal && modalShouldBeOpened ? this.componentModal.openModalTemplate : null; this.componentModal = this.createComponentModal(element, modalShouldBeOpened, currentValue); this.setOpenModalElement(openModalTemplate); } this.attached = true; this.element = element; element.component = this; // If this already has an id, get it from the dom. If SSR, it could be different from the initiated id. if (this.element.id) { this.id = this.element.id; this.component.id = this.id; } this.loadRefs(element, { messageContainer: 'single', tooltip: 'multiple' }); this.attachTooltips(this.refs.tooltip); // Attach logic. this.attachLogic(); this.autofocus(); // Allow global attach. this.hook('attachComponent', element, this); // Allow attach per component type. var type = this.component.type; if (type) { this.hook("attach".concat(type.charAt(0).toUpperCase() + type.substring(1, type.length)), element, this); } this.restoreFocus(); this.addons.forEach(function (addon) { return addon.attach(element); }); return _nativePromiseOnly.default.resolve(); } }, { key: "restoreFocus", value: function restoreFocus() { var _this$root2, _this$root2$focusedCo; var isFocused = ((_this$root2 = this.root) === null || _this$root2 === void 0 ? void 0 : (_this$root2$focusedCo = _this$root2.focusedComponent) === null || _this$root2$focusedCo === void 0 ? void 0 : _this$root2$focusedCo.path) === this.path; if (isFocused) { var _this$root$currentSel; this.loadRefs(this.element, { input: 'multiple' }); this.focus((_this$root$currentSel = this.root.currentSelection) === null || _this$root$currentSel === void 0 ? void 0 : _this$root$currentSel.index); this.restoreCaretPosition(); } } }, { key: "addShortcut", value: function addShortcut(element, shortcut) { // Avoid infinite recursion. if (!element || !this.root || this.root === this) { return; } if (!shortcut) { shortcut = this.component.shortcut; } this.root.addShortcut(element, shortcut); } }, { key: "removeShortcut", value: function removeShortcut(element, shortcut) { // Avoid infinite recursion. if (!element || this.root === this) { return; } if (!shortcut) { shortcut = this.component.shortcut; } this.root.removeShortcut(element, shortcut); } /** * Remove all event handlers. */ }, { key: "detach", value: function detach() { this.refs = {}; this.removeEventListeners(); this.detachLogic(); if (this.tooltip) { this.tooltip.destroy(); } } }, { key: "checkRefresh", value: function checkRefresh(refreshData, changed, flags) { var changePath = _lodash.default.get(changed, 'instance.path', false); // Don't let components change themselves. if (changePath && this.path === changePath) { return; } if (refreshData === 'data') { this.refresh(this.data, changed, flags); } else if (changePath && (0, FormioUtils.getComponentPath)(changed.instance) === refreshData && changed && changed.instance && // Make sure the changed component is not in a different "context". Solves issues where refreshOn being set // in fields inside EditGrids could alter their state from other rows (which is bad). this.inContext(changed.instance)) { this.refresh(changed.value, changed, flags); } } }, { key: "checkRefreshOn", value: function checkRefreshOn(changes) { var _this7 = this; var flags = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; changes = changes || []; if (flags.noRefresh) { return; } if (!changes.length && flags.changed) { changes = [flags.changed]; } var refreshOn = flags.fromBlur ? this.component.refreshOnBlur : this.component.refreshOn || this.component.redrawOn; // If they wish to refresh on a value, then add that here. if (refreshOn) { if (Array.isArray(refreshOn)) { refreshOn.forEach(function (refreshData) { return changes.forEach(function (changed) { return _this7.checkRefresh(refreshData, changed, flags); }); }); } else { changes.forEach(function (changed) { return _this7.checkRefresh(refreshOn, changed, flags); }); } } } /** * Refreshes the component with a new value. * * @param value */ }, { key: "refresh", value: function refresh(value) { if (this.hasOwnProperty('refreshOnValue')) { this.refreshOnChanged = !_lodash.default.isEqual(value, this.refreshOnValue); } else { this.refreshOnChanged = true; } this.refreshOnValue = (0, FormioUtils.fastCloneDeep)(value); if (this.refreshOnChanged) { if (this.component.clearOnRefresh) { this.setValue(null); } this.triggerRedraw(); } } /** * Checks to see if a separate component is in the "context" of this component. This is determined by first checking * if they share the same "data" object. It will then walk up the parent tree and compare its parents data objects * with the components data and returns true if they are in the same context. * * Different rows of the same EditGrid, for example, are in different contexts. * * @param component */ }, { key: "inContext", value: function inContext(component) { if (component.data === this.data) { return true; } var parent = this.parent; while (parent) { if (parent.data === component.data) { return true; } parent = parent.parent; } return false; } }, { key: "viewOnly", get: function get() { return this.options.readOnly && this.options.viewAsHtml; } }, { key: "createViewOnlyElement", value: function createViewOnlyElement() { this.element = this.ce('dl', { id: this.id }); if (this.element) { // Ensure you can get the component info from the element. this.element.component = this; } return this.element; } }, { key: "defaultViewOnlyValue", get: function get() { return '-'; } /** * Uses the widget to determine the output string. * * @param value * @return {*} */ }, { key: "getWidgetValueAsString", value: function getWidgetValueAsString(value, options) { var _this8 = this; var noInputWidget = !this.refs.input || !this.refs.input[0] || !this.refs.input[0].widget; if (!value || noInputWidget) { if (!this.widget || !value) { return value; } else { return this.widget.getValueAsString(value); } } if (Array.isArray(value)) { var values = []; value.forEach(function (val, index) { var widget = _this8.refs.input[index] && _this8.refs.input[index].widget; if (widget) { values.push(widget.getValueAsString(val, options)); } }); return values; } var widget = this.refs.input[0].widget; return widget.getValueAsString(value, options); } }, { key: "getValueAsString", value: function getValueAsString(value, options) { if (!value) { return ''; } value = this.getWidgetValueAsString(value, options); if (Array.isArray(value)) { return value.join(', '); } if (_lodash.default.isPlainObject(value)) {