UNPKG

formiojs

Version:

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

793 lines (650 loc) • 28.5 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/es.string.iterator.js"); require("core-js/modules/web.dom-collections.iterator.js"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; require("core-js/modules/es.array.concat.js"); require("core-js/modules/es.function.name.js"); require("core-js/modules/es.array.map.js"); require("core-js/modules/es.object.to-string.js"); require("core-js/modules/es.regexp.constructor.js"); require("core-js/modules/es.regexp.exec.js"); require("core-js/modules/es.regexp.to-string.js"); require("core-js/modules/es.string.replace.js"); require("core-js/modules/web.dom-collections.for-each.js"); require("core-js/modules/es.object.get-prototype-of.js"); var _TextField = _interopRequireDefault(require("../textfield/TextField")); var _lodash = _interopRequireDefault(require("lodash")); var _nativePromiseOnly = _interopRequireDefault(require("native-promise-only")); var _utils = require("../../utils/utils"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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 TextAreaComponent = /*#__PURE__*/function (_TextFieldComponent) { _inherits(TextAreaComponent, _TextFieldComponent); var _super = _createSuper(TextAreaComponent); function TextAreaComponent() { _classCallCheck(this, TextAreaComponent); return _super.apply(this, arguments); } _createClass(TextAreaComponent, [{ key: "init", value: function init() { _get(_getPrototypeOf(TextAreaComponent.prototype), "init", this).call(this); this.editors = []; this.editorsReady = []; this.updateSizes = []; // Never submit on enter for text areas. this.options.submitOnEnter = false; } }, { key: "defaultSchema", get: function get() { return TextAreaComponent.schema(); } }, { key: "inputInfo", get: function get() { var info = _get(_getPrototypeOf(TextAreaComponent.prototype), "inputInfo", this); info.type = this.component.wysiwyg ? 'div' : 'textarea'; if (this.component.rows) { info.attr.rows = this.component.rows; } return info; } }, { key: "validateMultiple", value: function validateMultiple() { return !this.isJsonValue; } }, { key: "renderElement", value: function renderElement(value, index) { var info = this.inputInfo; info.attr = info.attr || {}; info.content = value; if ((this.options.readOnly || this.disabled) && !this.isHtmlRenderMode()) { var elementStyle = this.info.attr.style || ''; var children = "<div ref=\"input\" class=\"formio-editor-read-only-content\" ".concat(elementStyle ? "style='".concat(elementStyle, "'") : '', "></div>"); return this.renderTemplate('well', { children: children, nestedKey: this.key, value: value }); } return this.renderTemplate('input', { prefix: this.prefix, suffix: this.suffix, input: info, value: value, index: index }); } }, { key: "autoExpand", get: function get() { return this.component.autoExpand; } /** * Updates the editor value. * * @param newValue */ }, { key: "updateEditorValue", value: function updateEditorValue(index, newValue) { newValue = this.getConvertedValue(this.trimBlanks(newValue)); var dataValue = this.dataValue; if (this.component.multiple && Array.isArray(dataValue)) { var newArray = _lodash.default.clone(dataValue); newArray[index] = newValue; newValue = newArray; } if (!_lodash.default.isEqual(newValue, dataValue) && (!_lodash.default.isEmpty(newValue) || !_lodash.default.isEmpty(dataValue))) { this.updateValue(newValue, { modified: !this.autoModified }, index); } this.autoModified = false; } }, { key: "attachElement", value: function attachElement(element, index) { var _this2 = this; if (this.autoExpand && (this.isPlain || this.options.readOnly || this.options.htmlView)) { if (element.nodeName === 'TEXTAREA') { this.addAutoExpanding(element, index); } } if (this.options.readOnly) { return element; } if (this.component.wysiwyg && !this.component.editor) { this.component.editor = 'ckeditor'; } var settings = _lodash.default.isEmpty(this.component.wysiwyg) ? this.wysiwygDefault[this.component.editor] || this.wysiwygDefault.default : this.component.wysiwyg; // Keep track of when this editor is ready. this.editorsReady[index] = new _nativePromiseOnly.default(function (editorReady) { // Attempt to add a wysiwyg editor. In order to add one, it must be included on the global scope. switch (_this2.component.editor) { case 'ace': if (!settings) { settings = {}; } settings.mode = _this2.component.as ? "ace/mode/".concat(_this2.component.as) : 'ace/mode/javascript'; _this2.addAce(element, settings, function (newValue) { return _this2.updateEditorValue(index, newValue); }).then(function (ace) { _this2.editors[index] = ace; var dataValue = _this2.dataValue; dataValue = _this2.component.multiple && Array.isArray(dataValue) ? dataValue[index] : dataValue; ace.setValue(_this2.setConvertedValue(dataValue, index)); editorReady(ace); return ace; }).catch(function (err) { return console.warn(err); }); break; case 'quill': // Normalize the configurations for quill. if (settings.hasOwnProperty('toolbarGroups') || settings.hasOwnProperty('toolbar')) { console.warn('The WYSIWYG settings are configured for CKEditor. For this renderer, you will need to use configurations for the Quill Editor. See https://quilljs.com/docs/configuration for more information.'); settings = _this2.wysiwygDefault.quill; } // Add the quill editor. _this2.addQuill(element, settings, function () { return _this2.updateEditorValue(index, _this2.editors[index].root.innerHTML); }).then(function (quill) { _this2.editors[index] = quill; if (_this2.component.isUploadEnabled) { var _this = _this2; quill.getModule('uploader').options.handler = function () { var _this$imageHandler; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } //we need initial 'this' because quill calls this method with its own context and we need some inner quill methods exposed in it //we also need current component instance as we use some fields and methods from it as well (_this$imageHandler = _this.imageHandler).call.apply(_this$imageHandler, [_this, this].concat(args)); }; } quill.root.spellcheck = _this2.component.spellcheck; if (_this2.options.readOnly || _this2.disabled) { quill.disable(); } var dataValue = _this2.dataValue; dataValue = _this2.component.multiple && Array.isArray(dataValue) ? dataValue[index] : dataValue; quill.setContents(quill.clipboard.convert({ html: _this2.setConvertedValue(dataValue, index) })); editorReady(quill); return quill; }).catch(function (err) { return console.warn(err); }); break; case 'ckeditor': settings = settings || {}; settings.rows = _this2.component.rows; _this2.addCKE(element, settings, function (newValue) { return _this2.updateEditorValue(index, newValue); }).then(function (editor) { _this2.editors[index] = editor; var dataValue = _this2.dataValue; dataValue = _this2.component.multiple && Array.isArray(dataValue) ? dataValue[index] : dataValue; var value = _this2.setConvertedValue(dataValue, index); var isReadOnly = _this2.options.readOnly || _this2.disabled; // Use ckeditor 4 in IE browser if ((0, _utils.getBrowserInfo)().ie) { editor.on('instanceReady', function () { editor.setReadOnly(isReadOnly); editor.setData(value); }); } else { var numRows = parseInt(_this2.component.rows, 10); if (_lodash.default.isFinite(numRows) && _lodash.default.has(editor, 'ui.view.editable.editableElement')) { // Default height is 21px with 10px margin + a 14px top margin. var editorHeight = numRows * 31 + 14; editor.ui.view.editable.editableElement.style.height = "".concat(editorHeight, "px"); } editor.isReadOnly = isReadOnly; editor.data.set(value); } editorReady(editor); return editor; }); break; default: _get(_getPrototypeOf(TextAreaComponent.prototype), "attachElement", _this2).call(_this2, element, index); break; } }); return element; } }, { key: "attach", value: function attach(element) { var attached = _get(_getPrototypeOf(TextAreaComponent.prototype), "attach", this).call(this, element); // Make sure we restore the value after attaching since wysiwygs and readonly texts need an additional set. this.restoreValue(); return attached; } }, { key: "imageHandler", value: function imageHandler(moduleInstance, range, files) { var _this3 = this; var quillInstance = moduleInstance.quill; if (!files || !files.length) { console.warn('No files selected'); return; } quillInstance.enable(false); var _this$component = this.component, uploadStorage = _this$component.uploadStorage, uploadUrl = _this$component.uploadUrl, uploadOptions = _this$component.uploadOptions, uploadDir = _this$component.uploadDir, fileKey = _this$component.fileKey; var requestData; this.fileService.uploadFile(uploadStorage, files[0], (0, _utils.uniqueName)(files[0].name), uploadDir || '', //should pass empty string if undefined null, uploadUrl, uploadOptions, fileKey).then(function (result) { requestData = result; return _this3.fileService.downloadFile(result); }).then(function (result) { quillInstance.enable(true); var Delta = Quill.import('delta'); quillInstance.updateContents(new Delta().retain(range.index).delete(range.length).insert({ image: result.url }, { alt: JSON.stringify(requestData) }), Quill.sources.USER); }).catch(function (error) { console.warn('Quill image upload failed'); console.warn(error); quillInstance.enable(true); }); } }, { key: "isPlain", get: function get() { return !this.component.wysiwyg && !this.component.editor; } }, { key: "htmlView", get: function get() { return this.options.readOnly && (this.component.editor || this.component.wysiwyg); } }, { key: "setValueAt", value: function setValueAt(index, value) { var _this4 = this; var flags = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; _get(_getPrototypeOf(TextAreaComponent.prototype), "setValueAt", this).call(this, index, value, flags); if (this.editorsReady[index]) { var setEditorsValue = function setEditorsValue(flags) { return function (editor) { if (!flags.skipWysiwyg) { _this4.autoModified = true; switch (_this4.component.editor) { case 'ace': editor.setValue(_this4.setConvertedValue(value, index)); break; case 'quill': if (_this4.component.isUploadEnabled) { _this4.setAsyncConvertedValue(value).then(function (result) { var content = editor.clipboard.convert({ html: result }); editor.setContents(content); }); } else { var convertedValue = _this4.setConvertedValue(value, index); var content = editor.clipboard.convert({ html: convertedValue }); editor.setContents(content); } break; case 'ckeditor': editor.data.set(_this4.setConvertedValue(value, index)); break; } } }; }; this.editorsReady[index].then(setEditorsValue(_lodash.default.clone(flags))); } } }, { key: "setValue", value: function setValue(value) { var _this5 = this; var flags = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (this.isPlain || this.options.readOnly || this.disabled) { value = this.component.multiple && Array.isArray(value) ? value.map(function (val, index) { return _this5.setConvertedValue(val, index); }) : this.setConvertedValue(value); return _get(_getPrototypeOf(TextAreaComponent.prototype), "setValue", this).call(this, value, flags); } flags.skipWysiwyg = _lodash.default.isEqual(value, this.getValue()); return _get(_getPrototypeOf(TextAreaComponent.prototype), "setValue", this).call(this, value, flags); } }, { key: "setContent", value: function setContent(element, content, forceSanitize) { _get(_getPrototypeOf(TextAreaComponent.prototype), "setContent", this).call(this, element, content, forceSanitize, { addAttr: ['allow', 'allowfullscreen', 'frameborder', 'scrolling'], addTags: ['iframe'] }); } }, { key: "setReadOnlyValue", value: function setReadOnlyValue(value, index) { index = index || 0; if (this.options.readOnly || this.disabled) { if (this.refs.input && this.refs.input[index]) { if (this.component.inputFormat === 'plain') { this.refs.input[index].innerText = this.interpolate(value, {}, { noeval: true }); } else { this.setContent(this.refs.input[index], this.interpolate(value, {}, { noeval: true }), this.shouldSanitizeValue); } } } } }, { key: "isJsonValue", get: function get() { return this.component.as && this.component.as === 'json'; } }, { key: "setConvertedValue", value: function setConvertedValue(value, index) { if (this.isJsonValue && !_lodash.default.isNil(value)) { try { value = JSON.stringify(value, null, 2); } catch (err) { console.warn(err); } } if (!_lodash.default.isString(value)) { value = ''; } this.setReadOnlyValue(value, index); return value; } }, { key: "setAsyncConvertedValue", value: function setAsyncConvertedValue(value) { if (this.isJsonValue && value) { try { value = JSON.stringify(value, null, 2); } catch (err) { console.warn(err); } } if (!_lodash.default.isString(value)) { value = ''; } var htmlDoc = new DOMParser().parseFromString(value, 'text/html'); var images = htmlDoc.getElementsByTagName('img'); if (images.length) { return this.setImagesUrl(images).then(function () { value = htmlDoc.getElementsByTagName('body')[0].innerHTML; return value; }); } else { return _nativePromiseOnly.default.resolve(value); } } }, { key: "setImagesUrl", value: function setImagesUrl(images) { var _this6 = this; return _nativePromiseOnly.default.all(_lodash.default.map(images, function (image) { var requestData; try { requestData = JSON.parse(image.getAttribute('alt')); } catch (error) { console.warn(error); } return _this6.fileService.downloadFile(requestData).then(function (result) { image.setAttribute('src', result.url); }); })); } }, { key: "addAutoExpanding", value: function addAutoExpanding(textarea, index) { var heightOffset = null; var previousHeight = null; var changeOverflow = function changeOverflow(value) { var width = textarea.style.width; textarea.style.width = '0px'; textarea.offsetWidth; textarea.style.width = width; textarea.style.overflowY = value; }; var preventParentScroll = function preventParentScroll(element, changeSize) { var nodeScrolls = []; while (element && element.parentNode && element.parentNode instanceof Element) { if (element.parentNode.scrollTop) { nodeScrolls.push({ node: element.parentNode, scrollTop: element.parentNode.scrollTop }); } element = element.parentNode; } changeSize(); nodeScrolls.forEach(function (nodeScroll) { nodeScroll.node.scrollTop = nodeScroll.scrollTop; }); }; var resize = function resize() { if (textarea.scrollHeight === 0) { return; } preventParentScroll(textarea, function () { textarea.style.height = ''; textarea.style.height = "".concat(textarea.scrollHeight + heightOffset, "px"); }); }; var update = _lodash.default.debounce(function () { resize(); var styleHeight = Math.round(parseFloat(textarea.style.height)); var computed = window.getComputedStyle(textarea, null); var currentHeight = textarea.offsetHeight; if (currentHeight < styleHeight && computed.overflowY === 'hidden') { changeOverflow('scroll'); } else if (computed.overflowY !== 'hidden') { changeOverflow('hidden'); } resize(); currentHeight = textarea.offsetHeight; if (previousHeight !== currentHeight) { previousHeight = currentHeight; update(); } }, 200); var computedStyle = window.getComputedStyle(textarea, null); textarea.style.resize = 'none'; heightOffset = parseFloat(computedStyle.borderTopWidth) + parseFloat(computedStyle.borderBottomWidth) || 0; if (window) { this.addEventListener(window, 'resize', update); } this.addEventListener(textarea, 'input', update); this.on('initialized', update); this.updateSizes[index] = update; update(); } }, { key: "trimBlanks", value: function trimBlanks(value) { if (!value || this.isPlain) { return value; } var trimBlanks = function trimBlanks(value) { var nbsp = '<p>&nbsp;</p>'; var br = '<p><br></p>'; var brNbsp = '<p><br>&nbsp;</p>'; var regExp = new RegExp("^".concat(nbsp, "|").concat(nbsp, "$|^").concat(br, "|").concat(br, "$|^").concat(brNbsp, "|").concat(brNbsp, "$"), 'g'); return typeof value === 'string' ? value.replace(regExp, '') : value; }; if (Array.isArray(value)) { value.forEach(function (input, index) { value[index] = trimBlanks(input); }); } else { value = trimBlanks(value); } return value; } }, { key: "onChange", value: function onChange(flags, fromRoot) { var changed = _get(_getPrototypeOf(TextAreaComponent.prototype), "onChange", this).call(this, flags, fromRoot); this.updateSizes.forEach(function (updateSize) { return updateSize(); }); return changed; } }, { key: "hasChanged", value: function hasChanged(newValue, oldValue) { return _get(_getPrototypeOf(TextAreaComponent.prototype), "hasChanged", this).call(this, this.trimBlanks(newValue), this.trimBlanks(oldValue)); } }, { key: "isEmpty", value: function isEmpty() { var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.dataValue; return _get(_getPrototypeOf(TextAreaComponent.prototype), "isEmpty", this).call(this, this.trimBlanks(value)); } }, { key: "defaultValue", get: function get() { var defaultValue = _get(_getPrototypeOf(TextAreaComponent.prototype), "defaultValue", this); if (this.component.editor === 'quill' && !defaultValue) { defaultValue = '<p><br></p>'; } return defaultValue; } }, { key: "getConvertedValue", value: function getConvertedValue(value) { if (this.isJsonValue && value) { try { value = JSON.parse(value); } catch (err) {// console.warn(err); } } return value; } }, { key: "detach", value: function detach() { var _this7 = this; // Destroy all editors. this.editors.forEach(function (editor) { if (editor.destroy) { editor.destroy(); } }); this.editors = []; this.editorsReady = []; this.updateSizes.forEach(function (updateSize) { return _this7.removeEventListener(window, 'resize', updateSize); }); this.updateSizes = []; _get(_getPrototypeOf(TextAreaComponent.prototype), "detach", this).call(this); } }, { key: "getValue", value: function getValue() { if (this.isPlain) { return this.getConvertedValue(_get(_getPrototypeOf(TextAreaComponent.prototype), "getValue", this).call(this)); } return this.dataValue; } }, { key: "focus", value: function focus() { _get(_getPrototypeOf(TextAreaComponent.prototype), "focus", this).call(this); switch (this.component.editor) { case 'ckeditor': { var _this$editors$0$editi, _this$editors$0$editi2; if ((_this$editors$0$editi = this.editors[0].editing) !== null && _this$editors$0$editi !== void 0 && (_this$editors$0$editi2 = _this$editors$0$editi.view) !== null && _this$editors$0$editi2 !== void 0 && _this$editors$0$editi2.focus) { this.editors[0].editing.view.focus(); } this.element.scrollIntoView(); break; } case 'ace': { this.editors[0].focus(); this.element.scrollIntoView(); break; } case 'quill': { this.editors[0].focus(); break; } } } }], [{ key: "schema", value: function schema() { for (var _len2 = arguments.length, extend = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { extend[_key2] = arguments[_key2]; } return _TextField.default.schema.apply(_TextField.default, [{ type: 'textarea', label: 'Text Area', key: 'textArea', rows: 3, wysiwyg: false, editor: '', fixedSize: true, inputFormat: 'html', validate: { minWords: '', maxWords: '' } }].concat(extend)); } }, { key: "builderInfo", get: function get() { return { title: 'Text Area', group: 'basic', icon: 'font', documentation: '/userguide/#textarea', weight: 20, schema: TextAreaComponent.schema() }; } }]); return TextAreaComponent; }(_TextField.default); exports.default = TextAreaComponent;