/* * This file is part of the TYPO3 CMS project. * * It is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License, either version 2 * of the License, or any later version. * * For the full copyright and license information, please read the * LICENSE.txt file that was distributed with this source code. * * The TYPO3 project - inspiring people to share! */ import{DateTime as p}from"luxon";import y from"@typo3/backend/hashing/md5.js";import g from"@typo3/backend/modal.js";import w from"@typo3/backend/severity.js";import b from"@typo3/backend/utility.js";import k from"@typo3/core/event/regular-event.js";import E from"@typo3/core/event/throttle-event.js";import x from"@typo3/backend/utility/dom-helper.js";import{selector as d}from"@typo3/core/literals.js";import N from"@typo3/backend/form/submit-interceptor.js";import{FormEngineReview as T}from"@typo3/backend/form-engine-review.js";import v from"~labels/core.core";import C from"~labels/core.mod_web_list";let o,S=!1;const h=new Map;class a{static{this.rulesSelector="[data-formengine-validation-rules]"}static{this.inputSelector="[data-formengine-input-params]"}static{this.markerSelector=".t3js-formengine-validation-marker"}static{this.labelSelector=".t3js-formengine-label"}static{this.errorClass="has-error"}static{this.validationErrorClass="has-validation-error"}static{this.passwordDummy="********"}static initialize(t){o=t,o.formElement.querySelectorAll("."+a.errorClass).forEach(e=>e.classList.remove(a.errorClass)),a.initializeInputFields(),new T(o.formElement),new k("change",(e,s)=>{a.validateField(s),o.markFieldAsChanged(s)}).delegateTo(o.formElement,a.rulesSelector),new E("input",(e,s)=>{a.validateField(s)},100).delegateTo(o.formElement,a.rulesSelector),a.registerSubmitCallback(),a.validate()}static initializeInputFields(){o.formElement.querySelectorAll(a.inputSelector).forEach(t=>{if("formengineInputInitialized"in t.dataset)return;const s=JSON.parse(t.dataset.formengineInputParams).field,r=o.formElement.querySelector(d`[name="${s}"]`);r.dataset.config=t.dataset.formengineInputParams,a.initializeInputField(s)})}static initializeInputField(t){const e=o.formElement.querySelector(d`[name="${t}"]`),s=o.formElement.querySelector(d`[data-formengine-input-name="${t}"]`);if(e.dataset.config!==void 0){const r=JSON.parse(e.dataset.config),i=a.formatByEvals(r,e.value);i.length&&(s.value=i)}new k("change",()=>{a.updateInputField(s.dataset.formengineInputName)}).bindTo(s),s.dataset.formengineInputInitialized="true",s.dispatchEvent(new Event("formengine:input:initialized"))}static registerCustomEvaluation(t,e){h.has(t)||h.set(t,e)}static formatByEvals(t,e){if(t.evalList!==void 0){const s=b.trimExplode(",",t.evalList);for(const r of s)e=a.formatValue(r,e)}return e}static formatValue(t,e){switch(t){case"date":case"datetime":case"time":case"timesec":case"datetimesec":if(e==="")return"";const s=p.fromISO(String(e));if(!s.isValid)throw new Error("Invalid ISO8601 DateTime string: "+e);return s.toISO({suppressMilliseconds:!0,includeOffset:!1});case"password":return e?a.passwordDummy:"";default:return e.toString()}}static updateInputField(t){const e=o.formElement.querySelector(d`[name="${t}"]`),s=o.formElement.querySelector(d`[data-formengine-input-name="${t}"]`);if(e.dataset.config!==void 0){const r=JSON.parse(e.dataset.config),i=a.processByEvals(r,s.value),u=a.formatByEvals(r,i);e.value!==i&&(e.disabled&&e.dataset.enableOnModification&&(e.disabled=!1),e.value=i,e.dispatchEvent(new Event("change"))),s.value!==u&&(s.value=u)}}static validateField(t){if(t.dataset.formengineValidationRules===void 0)return;let e=t.value||"";const s=JSON.parse(t.dataset.formengineValidationRules);let r=!1,i=0,u,n,c;Array.isArray(e)||(e=e.trimStart());for(const l of s){if(r)break;switch(l.type){case"required":e===""&&(r=!0,t.classList.add(a.errorClass),t.closest(a.markerSelector)?.querySelector(a.labelSelector)?.classList.add(a.errorClass));break;case"range":if(e!==""){if((l.minItems||l.maxItems)&&(u=o.formElement.querySelector(d`[name="${t.dataset.relatedfieldname}"]`),u!==null?i=b.trimExplode(",",u.value).length:i=parseInt(t.value,10),l.minItems!==void 0&&(n=l.minItems*1,!isNaN(n)&&ic&&(r=!0))),l.lower!==void 0)if(t.dataset.inputType==="datetimepicker"){const m=p.fromISO(e,{zone:"utc"}),I=p.fromISO(l.lower,{zone:"utc"});(!m.isValid||mI.plus((59-I.second)*1e3))&&(r=!0)}else{const m=l.upper*1;!isNaN(m)&&parseInt(e,10)>m&&(r=!0)}}break;case"select":case"category":(l.minItems||l.maxItems)&&(u=o.formElement.querySelector(d`[name="${t.dataset.relatedfieldname}"]`),u!==null?i=b.trimExplode(",",u.value).length:t instanceof HTMLSelectElement?i=t.querySelectorAll("option:checked").length:i=t.querySelectorAll("input[value]:checked").length,l.minItems!==void 0&&(n=l.minItems*1,!isNaN(n)&&ic&&(r=!0)));break;case"group":case"folder":(l.minItems||l.maxItems)&&(i=b.trimExplode(",",t.value).length,l.minItems!==void 0&&(n=l.minItems*1,!isNaN(n)&&ic&&(r=!0)));break;case"inline":(l.minItems||l.maxItems)&&(i=b.trimExplode(",",t.value).length,l.minItems!==void 0&&(n=l.minItems*1,!isNaN(n)&&ic&&(r=!0)));break;case"min":(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement)&&t.value.length>0&&t.value.length="a"&&c<="z"||c>="A"&&c<="Z",m=c>="0"&&c<="9";switch(t){case"alphanum":f=!1;break;case"alpha":m=!1,f=!1;break;case"num":l=!1,f=!1;break;default:break}(l||m||f)&&(r+=c)}r!==e&&(n=r);break;case"is_in":if(s.is_in){i=""+e,s.is_in=s.is_in.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&");const c=new RegExp("[^"+s.is_in+"]+","g");r=i.replace(c,"")}else r=i;n=r;break;case"nospace":n=(""+e).replace(/ /g,"");break;case"md5":e!==""&&(n=y.hash(e));break;case"upper":n=e.toUpperCase();break;case"lower":n=e.toLowerCase();break;case"integer":e!==""&&(n=a.parseInt(e).toString());break;case"decimal":e!==""&&(n=a.parseDouble(e));break;case"trim":n=String(e).trim();break;case"time":case"timesec":e!==""&&(n=p.fromISO(e).set({year:1970,month:1,day:1}).toISO({suppressMilliseconds:!0,includeOffset:!1}));break;case"null":break;case"password":break;default:h.has(t)?n=h.get(t).call(null,e):typeof TBE_EDITOR=="object"&&TBE_EDITOR.customEvalFunctions!==void 0&&typeof TBE_EDITOR.customEvalFunctions[t]=="function"&&(n=TBE_EDITOR.customEvalFunctions[t](e))}return n}static validate(t){(typeof t>"u"||t instanceof Document)&&o.formElement.querySelectorAll(a.markerSelector+', [role="tablist"] > .nav-item').forEach(s=>{s.classList.remove(a.validationErrorClass)});const e=t||document;for(const s of e.querySelectorAll(a.rulesSelector))s.closest(".t3js-flex-section-deleted, .t3js-inline-record-deleted, .t3js-file-reference-deleted")===null&&a.validateField(s)}static parseInt(t){const e=""+t;if(!t)return 0;const s=parseInt(e,10);return isNaN(s)?0:s}static parseDouble(t,e=2){let s=""+t;s=s.replace(/[^0-9,.-]/g,"");const r=s.startsWith("-");s=s.replace(/-/g,""),s=s.replace(/,/g,"."),s.indexOf(".")===-1&&(s+=".0");const i=s.split("."),u=i.pop();let n=+(i.join("")+"."+u);return r&&(n*=-1),s=n.toFixed(e),s}static markParentTab(t,e){x.parents(t,".tab-pane").forEach(r=>{e&&(e=r.querySelector(".has-error")===null);const i=r.id;o.formElement.querySelector(d`[data-typo3-tab="${"#"+i}"]`).closest(".nav-item").classList.toggle(a.validationErrorClass,!e)})}static suspend(){S=!0}static resume(){S=!1}static isValid(){return document.querySelector("."+a.errorClass)===null}static showErrorModal(){const t=g.confirm(v.get("labels.fieldsMissing.title"),v.get("labels.fieldsMissing"),w.error,[{text:C.get("button.ok"),active:!0,btnClass:"btn-default",name:"ok"}]);t.addEventListener("button.clicked",()=>t.hideModal())}static registerSubmitCallback(){new N(o.formElement).addPreSubmitCallback(()=>S||a.isValid()?!0:(a.showErrorModal(),!1))}}export{a as default};