powerpagestoolkit 3.0.5002 → 3.0.5011
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/core/API.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +2 -2
- package/package.json +1 -1
package/dist/src/core/API.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ declare abstract class API {
|
|
|
27
27
|
/**
|
|
28
28
|
* More flexible method for building completely custom queries
|
|
29
29
|
*/
|
|
30
|
-
static request(query: string, options
|
|
30
|
+
static request<T>(query: string, options?: JQuery.AjaxSettings): Promise<T | Error>;
|
|
31
31
|
/**
|
|
32
32
|
*
|
|
33
33
|
* @param tableSetName The dataverse set name of the table being queried
|
package/dist/src/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* @ts-self-types="./index.d.ts" */
|
|
2
|
-
function g(r){let e=$.Deferred();return shell.getTokenDeferred().done(function(t){r.headers?r.headers.__RequestVerificationToken=t:$.extend(r,{headers:{__RequestVerificationToken:t}}),$.ajax(r).done(function(i,s,n){validateLoginSession(i,s,n,e.resolve)}).fail(e.reject)}).fail(function(){e.rejectWith(this,arguments)}),e.promise()}var S=class{static createRecord(e,t){return new Promise((i,s)=>{g({type:"POST",url:`/_api/${e}`,data:JSON.stringify(t),contentType:"application/json",success:function(n,o,l){i(l.getResponseHeader("entityid"))},error:n=>{s(n)}})})}static getRecord(e,t,i){return new Promise((s,n)=>{let o=`/_api/${e}(${t})${i?`${i}`:""}`;g({type:"GET",url:o,success:s,error:n})})}static request(e,t){return new Promise((i,s)=>{let n=`/_api/${e}`;g({url:n,...t})})}static getMultiple(e,t){return new Promise((i,s)=>{let n=`/_api/${e}${t?`?${t}`:""}`;g({type:"GET",url:n,success:function(o){i(o.value)},error:s})})}static updateRecord(e,t,i){return new Promise((s,n)=>{let o=`/_api/${e}(${t})`;g({type:"PATCH",url:o,data:JSON.stringify(i),success:s,error:n})})}},H=S;var b=class{defaultVisibility;set defaultDisplay(e){this.defaultVisibility=e}constructor(e){if(this.visibilityController=e,e.tagName==="TABLE"){let i=e.closest("fieldset");i&&(this.visibilityController=i)}if(["SPAN","INPUT","TEXTAREA","SELECT","TABLE"].includes(e.tagName)){let i=e.closest("td");i&&(this.visibilityController=i)}this.defaultVisibility=this.visibilityController.style.display}hide(){this.visibilityController.style.display="none"}show(){this.visibilityController.style.display=this.defaultVisibility}toggleVisibility(e){e?this.show():this.hide()}getVisibility(){return window.getComputedStyle(this.visibilityController).display!=="none"&&window.getComputedStyle(this.visibilityController).visibility!=="hidden"&&this.visibilityController.getBoundingClientRect().height>0&&this.visibilityController.getBoundingClientRect().width>0}destroy(){this.visibilityController=null,this.defaultVisibility=null}};var N={CHECKBOX:"click",RADIO:"click",SELECT:"change",TEXT:"keyup",DEFAULT:"input"};var h=Symbol("init"),p=Symbol("destroy");var v=class extends HTMLElement{flyoutContent;icon;observers=[];constructor(e,t){if(super(),typeof e!="string")throw new Error(`argument "titleString" must be of type "string". Received: "${typeof e}"`);if(t&&typeof t!="object")throw new Error(`argument "iconStyle" must be of type "object". Received: "${typeof t}"`);this.classList.add("info-icon"),this.icon=document.createElement("i"),this.icon.classList.add("fa","fa-solid","fa-info-circle"),this.icon.setAttribute("aria-label","Info"),this.icon.style.cursor="pointer",this.flyoutContent=document.createElement("div"),this.flyoutContent.innerHTML=e,this.flyoutContent.classList.add("flyout-content"),this.appendChild(this.icon),this.appendChild(this.flyoutContent),t&&Object.assign(this.icon.style,t),this.handleClick=this.handleClick.bind(this),this.handleResize=this.handleResize.bind(this),this.handleTouchStart=this.handleTouchStart.bind(this),this.handleMouseEnter=this.handleMouseEnter.bind(this),this.handleMouseLeave=this.handleMouseLeave.bind(this),this.handleScroll=this.handleScroll.bind(this),this.flyoutContent.style.minWidth=this.getDesiredWidth(),this.flyoutContent.style.display="none",this.attachEventListeners(),this.setupObservers()}attachEventListeners(){document.body.addEventListener("click",this.handleClick),self.addEventListener("resize",this.handleResize),this.icon.addEventListener("touchstart",this.handleTouchStart),this.addEventListener("mouseenter",this.handleMouseEnter),this.addEventListener("mouseleave",this.handleMouseLeave),self.addEventListener("scroll",this.handleScroll)}setupObservers(){let e=new MutationObserver(i=>{for(let s of i)for(let n of Array.from(s.removedNodes))if(n===this){this.destroy();return}});e.observe(document,{childList:!0,subtree:!0,attributes:!1});let t=new MutationObserver(()=>this.updateFlyoutWidth);t.observe(document,{childList:!0,subtree:!0,attributes:!1}),this.observers.push(e,t)}getDesiredWidth(){let e=self.innerWidth;return`${Math.min(e-40,600)}px`}positionFlyout(){this.flyoutContent.style.display="block";let e=this.icon.getBoundingClientRect(),t=this.flyoutContent.getBoundingClientRect(),i=self.innerHeight,n=e.bottom-5;n+t.height>i&&(n=e.top-t.height),this.flyoutContent.style.top=`${n}px`}updateFlyoutWidth(){this.flyoutContent.style.minWidth=this.getDesiredWidth()}handleClick(e){this.contains(e.target)||(this.flyoutContent.style.display="none")}handleResize(e){this.flyoutContent.style.minWidth=this.getDesiredWidth()}handleTouchStart(){this.flyoutContent.style.display=this.flyoutContent.style.display==="block"?"none":"block",this.flyoutContent.style.display==="block"&&this.positionFlyout()}handleMouseEnter(e){this.positionFlyout()}handleMouseLeave(e){let t=e.relatedTarget;this.contains(t)||(this.flyoutContent.style.display="none")}handleScroll(){let e=this.flyoutContent.style.display;e!=="none"&&(this.positionFlyout(),this.flyoutContent.style.display=e)}destroy(){document.body.removeEventListener("click",this.handleClick),self.removeEventListener("resize",this.handleResize),this.icon.removeEventListener("touchstart",this.handleTouchStart),this.removeEventListener("mouseenter",this.handleMouseEnter),this.removeEventListener("mouseleave",this.handleMouseLeave),self.removeEventListener("scroll",this.handleScroll),this.observers.forEach(e=>e.disconnect())}},U=`info-icon-${crypto.randomUUID()}`;customElements.define(U,v);function E(r,e=document,t=!1,i){return new Promise((s,n)=>{if(t){let o,l=[],a=new Set;if(i<1)return s(Array.from(e.querySelectorAll(r)));let c=new MutationObserver(()=>{Array.from(e.querySelectorAll(r)).forEach(V=>{a.has(V)||(a.add(V),l.push(V))}),clearTimeout(o),o=setTimeout(()=>{l.length>0?(c.disconnect(),s(l)):n(new Error(`No elements found with target: "${r}" within ${i/1e3} seconds. If the element you are expecting has not loaded yet, consider raising your timeout.`))},i)});c.observe(e,{childList:!0,subtree:!0,attributes:!1})}else{let o=new MutationObserver(()=>{let c=e.querySelector(r);c&&(clearTimeout(l),o.disconnect(),s(c))}),l=setTimeout(()=>{o.disconnect(),n(new Error(`Element not found by target: "${r}" within ${i/1e3} second. If the element you are expecting has not loaded yet, consider raising your timeout.`))},i),a=e.querySelector(r);if(a)return clearTimeout(l),s(a);o.observe(e,{subtree:!0,attributes:!0,childList:!0})}})}var m=class extends Error{node;constructor(e,t){super(t),this.node=e,Object.setPrototypeOf(this,new.target.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}},k=class extends m{constructor(e,t){super(e,`There was an error initializing a DOMNodeReference for target: ${e.target}, :: ${t}`)}},I=class extends m{constructor(e){super(e,`The targeted DOM element was not found: ${e.target}`)}},F=class extends m{constructor(e){super(e,"Page_Validators could not be found")}},A=class extends m{constructor(e){super(e,`Error applying business rule to target: ${e.target}`)}},_=class extends m{constructor(e){super(e,"Self-referential dependency found. A DOMNodeReference cannot depend on itself")}},B=class extends m{constructor(e){super(e,`No label could be found for the target: ${e.target}`)}},q=class extends m{constructor(e,t,i,s,n){let o=s.join(" or ");super(e,`${t} expects ${i} to be of type ${o}. Received: ${n===null?"null":typeof n}`)}},G={NodeNotFoundError:I,InitializationError:k,Page_ValidatorsNotFoundError:F,BusinessRuleError:A,SelfReferenceError:_,LabelNotFoundError:B,IncorrectParameterError:q},u=G;import j from"DOMPurify";var f=class r{static instances=[];target;logicalName;root;timeoutMs;isLoaded;get value(){return this.valueManager.value}set value(e){this.valueManager.setValue(e)}get checked(){return this.valueManager.checked}set defaultDisplay(e){this.visibilityManager.defaultDisplay=e}visibilityManager;valueManager;eventManager;constructor(e,t=document.body,i){this.target=e,this.logicalName=this._extractLogicalName(e),this.root=t,this.timeoutMs=i,this.isLoaded=!1}async[h](){if(this.target instanceof HTMLElement?this.element=this.target:this.element=await E(this.target,this.root,!1,this.timeoutMs),!this.element)throw new u.NodeNotFoundError(this)}_extractLogicalName(e){if(typeof e!="string")return"";let t=e.match(/\[([^\]]+)\]/);if(!t)return e.replace(/[#\[\]]/g,"");let i=t[1];return(i.match(/["']([^"']+)["']/)?.[1]||i).replace(/[#\[\]]/g,"")}_valueSync(){if(!this._isValidFormElement(this.element))return;this.updateValue();let e=this._determineEventType();this.eventManager.registerDOMEventListener(this.element,e,this.updateValue.bind(this)),this._isDateInput()&&this._dateSync(this.element)}_determineEventType(){return this.element instanceof HTMLSelectElement?"change":this.element instanceof HTMLTextAreaElement?"keyup":this.element instanceof HTMLInputElement?N[this.element.type.toUpperCase()]||N.DEFAULT:N.DEFAULT}_isDateInput(){return this.element instanceof HTMLInputElement&&this.element.dataset.type==="date"}_isValidFormElement(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSpanElement||e instanceof HTMLButtonElement||e instanceof HTMLFieldSetElement}async _dateSync(e){let t=e.parentElement;if(!t)throw new DOMException("Date input must have a parent element");let i=await E("[data-date-format]",t,!1,1500);this.valueManager.element=i,this.eventManager.registerDOMEventListener(i,"select",this.updateValue.bind(this))}_bindMethods(){let e=Object.getPrototypeOf(this);for(let t of Object.getOwnPropertyNames(e)){let i=this[t];t!=="constructor"&&typeof i=="function"&&(this[t]=i.bind(this))}}[p](){this.isLoaded=!1,this.value=null,this.eventManager.destroy(),this.eventManager=null,this.visibilityManager.destroy(),this.visibilityManager=null,this.valueManager.destroy(),this.valueManager=null}async updateValue(e){e&&!e.isTrusted||(await this.valueManager.updateValue(e),this.triggerDependentsHandlers())}triggerDependentsHandlers(){this.eventManager.dispatchDependencyHandlers()}on(e,t){if(typeof t!="function")throw new u.IncorrectParameterError(this,"on","eventHandler",["function"],typeof t);let i=t;return this.eventManager.registerDOMEventListener(this.element,e,i.bind(this)),this}hide(){return this.visibilityManager.hide(),this}show(){return this.visibilityManager.show(),this}toggleVisibility(e){let t=e instanceof Function?e.call(this):e;return this.visibilityManager.toggleVisibility(t),this}setValue(e){return e instanceof Function&&(e=e()),this.valueManager.setValue(e),this}disable(){return this.element.disabled=!0,this}clearValue(){this.valueManager.clearValue(),this._getChildren()&&this.callAgainstChildrenInputs(e=>e.clearValue())}_getChildren(){let t=Array.from(this.element.querySelectorAll("input, select, textarea")).map(s=>s.id),i=r.instances.filter(s=>t.includes(s.element.id));return i.length>0?i:null}callAgainstChildrenInputs(e){let t=this._getChildren();if(!t){console.error("No child inputs found for target: ",this);return}for(let i of t)e(i)}enable(){return this.element.disabled=!1,this}prepend(...e){return this.element.prepend(...e),this}append(...e){return this.element.append(...e),this}before(...e){return this.element.before(...e),this}after(...e){return this.element.after(...e),this}getLabel(){let e=document.querySelector(`#${this.element.id}_label`)||null;if(!e)throw new u.LabelNotFoundError(this);return e}addLabelTooltip(e,t){let i=j.sanitize(e);return this.getLabel()?.append(new v(i,t||void 0)),this}addTooltip(e,t){let i=j.sanitize(e);return this.append(new v(i,t||void 0)),this}set innerHTML(e){let t=j.sanitize(e);this.element.innerHTML=t}remove(){return this.element.remove(),this}setStyle(e){if(e===null||typeof e!="object")throw new u.IncorrectParameterError(this,"setStyle","options",["Partial<CSSStyleDeclaration>"],typeof e);return Object.entries(e).forEach(([t,i])=>{i!==void 0&&(this.element.style[t]=i)}),this}applyBusinessRule(e,t){try{e.setRequirements&&this._setupRequirementsValidator(e.setRequirements());let i=this._createBusinessRuleHandler(e);return i(),t.length&&this._configureDependencyTracking(i,t),this}catch(i){throw i instanceof Error?i:new u.BusinessRuleError(this)}}_setupRequirementsValidator(e){let{isRequired:t,isValid:i}=e;if(typeof Page_Validators>"u")throw new u.Page_ValidatorsNotFoundError(this);let s=()=>!0;t&&i?s=()=>{let n=t.call(this),o=this.visibilityManager.getVisibility();return!n||o&&i.call(this,n)}:i?s=()=>this.visibilityManager.getVisibility()&&i.call(this,!1):t&&(s=()=>this.visibilityManager.getVisibility()&&t.call(this)),this._createValidator(s)}_createBusinessRuleHandler(e){return()=>{let t=!1;if(e.setVisibility){let s=e.setVisibility.call(this);t=!s,this.toggleVisibility(s)}if(e.setRequirements&&e.setRequirements().isRequired){let{isRequired:i}=e.setRequirements();this.setRequiredLevel(i.call(this))}if(e.setValue){let{condition:i,value:s}=e.setValue();if(i.call(this)){let n=s instanceof Function?s():s;this.setValue.call(this,n)}}e.setDisabled&&(e.setDisabled.call(this)?this.disable():this.enable()),t&&!e.setValue&&this.clearValue(),this.triggerDependentsHandlers()}}_createValidator(e){let t=(()=>{let n=this.getLabel();if(!n)throw new u.LabelNotFoundError(this);return n=n.innerHTML,n.length>50&&(n=n.substring(0,50)+"..."),n})(),i=`${this.element.id}Validator`,s=document.createElement("span");if(s.style.display="none",s.id=i,Object.assign(s,{controltovalidate:this.element.id,errormessage:`<a href='#${this.element.id}_label'>${t} is a required field</a>`,evaluationfunction:e.bind(this)}),Page_Validators==null)throw new u.Page_ValidatorsNotFoundError(this);Page_Validators.push(s)}_configureDependencyTracking(e,t){if(t.length<1){console.error(`powerpagestoolkit: No dependencies specified for ${this.element.id}. Include all required nodes in the dependency array for proper tracking.`);return}t.forEach(i=>{if(!i||!(i instanceof r))throw new TypeError("Each dependency must be a valid DOMNodeReference instance");if(i.logicalName===this.logicalName)throw new u.SelfReferenceError(this);i.eventManager.registerDependent(this,e.bind(this))})}setRequiredLevel(e){return e instanceof Function?(e.call(this)?this.getLabel()?.classList.add("required-field"):this.getLabel()?.classList.remove("required-field"),this):(e?this.getLabel()?.classList.add("required-field"):this.getLabel()?.classList.remove("required-field"),this)}onceLoaded(e){if(this.isLoaded){e(this);return}if(this.target instanceof HTMLElement){e(this);return}let t=new MutationObserver(function(){document.querySelector(this.target)&&(t.disconnect(),this.isLoaded=!0,e(this))}.bind(this));this.eventManager.registerObserver(t,{nodeToObserve:document.body,options:{subtree:!0,childList:!0}})}};var M=class{constructor(){}onFocus(){setTimeout(()=>this.input.select(),0)}onBlur(){this.formatInput()}setValue(e){this.input.value=String(e)}};var R=class extends M{input;options;constructor(e,t={}){super(),this.input=e,this.options={format:t.format||"(xxx) xxx-xxxx",countryCode:t.countryCode||"",countryCodeFormat:t.countryCodeFormat||"+"},this.onFocus=this.onFocus.bind(this),this.formatInput=this.formatInput.bind(this),this.onBlur=this.onBlur.bind(this),this.setupEventListeners(),setTimeout(()=>{this.formatInput()},0)}setupEventListeners(){this.input.addEventListener("focus",this.onFocus),this.input.addEventListener("input",this.formatInput),this.input.addEventListener("blur",this.onBlur)}formatInput(){let e=this.input.value,t=this.input.selectionStart||0,i=e.length,s=e.replace(/\D/g,""),n=this.formatPhoneNumber(s);this.input.value=n;let o=Math.min(t+(n.length-i),n.length);this.input.setSelectionRange(o,o)}formatPhoneNumber(e){if(!e)return"";let t=e,i="";if(this.options.countryCode){let a=this.options.countryCode.length;e.length>a?(i=e.substring(0,a),t=e.substring(a)):(i=e,t="")}let s="";if(i)switch(this.options.countryCodeFormat){case"+":s=`+${i} `;break;case"()":s=`(${i}) `;break;case"00":s=`00${i} `;break;default:s=`+${i} `}let n=this.options.format,o=0;for(let a=0;a<n.length&&o<t.length;a++)n[a]==="x"&&(n=n.substring(0,a)+t[o++]+n.substring(a+1));n=n.replace(/x/g,"");let l=n.split("").findIndex((a,c)=>!/\d/.test(a)&&n.substring(c).indexOf("x")===-1&&n.substring(c).replace(/[\s\-()]/g,"").length===0);return l!==-1&&(n=n.substring(0,l)),s+n}onFocus(){setTimeout(()=>this.input.select(),0)}onBlur(){this.formatInput();let e=this.getDigits(),t=this.options.countryCode?7+this.options.countryCode.length:7;e.length<t}getDigits(){return this.input.value.replace(/\D/g,"")}getCountryCode(){if(!this.options.countryCode)return"";let e=this.getDigits(),t=this.options.countryCode.length;return e.length>=t?e.substring(0,t):e}getPhoneDigits(){if(!this.options.countryCode)return this.getDigits();let e=this.getDigits(),t=this.options.countryCode.length;return e.length>t?e.substring(t):""}setValue(e){let t=e.replace(/\D/g,"");this.input.value=this.formatPhoneNumber(t)}isValid(){let e=this.getPhoneDigits(),t=this.getCountryCode();return(!this.options.countryCode||t.length===this.options.countryCode.length)&&e.length>=10}destroy(){this.input.removeEventListener("focus",this.onFocus),this.input.removeEventListener("input",this.formatInput),this.input.removeEventListener("blur",this.onBlur)}};var w=class{events=new Map;listeners=new Map;dependencyHandlers=new Set;observers=[];boundListeners=[];constructor(){}dispatchDependencyHandlers(){for(let[e,t]of this.dependencyHandlers)t.call(e)}registerDependent(e,t){try{return this.dependencyHandlers.add([e,t]),"success"}catch{return new Error(`Failed register dependant: ${e.target}`)}}registerEvent(e,t){return this.events.has(e)?(console.error("Event registration has already been defined for: ",e),new Error(`Event registration has already been defined for: ${e}`)):(this.listeners.set(e,new Set),this.events.set(e,t),"success")}registerListener(e,t){if(this.events.has(e)){let i=this.listeners.get(e)??new Set;return i.add(t),this.listeners.set(e,i),"success"}else return console.error("No event registration found for: ",e),new Error(`No event registration found for: ${e}`)}emit(e,...t){if(this.events.has(e)){let i=this.events.get(e),s=this.listeners.get(e);if(!s)return;for(let n of s)i.call(n,...t)}else console.error("Event not found in EventRegistry: ",e)}stopListening(e){for(let[t,i]of this.listeners)i.has(e)&&i.delete(e)}registerObserver(e,t){let{nodeToObserve:i,options:s}=t;e.observe(i,s),this.observers.push(e)}registerDOMEventListener(e,t,i){e.addEventListener(t,i),this.boundListeners.push({element:e,handler:i,event:t})}destroy(){this.boundListeners?.forEach(e=>{e.element?.removeEventListener(e.event,e.handler)}),this.boundListeners=[],this.observers?.forEach(e=>{e.disconnect()}),this.observers=[],this.events.clear(),this.dependencyHandlers.clear(),this.listeners.clear()}};var d=class extends f{radioType;constructor(e,t,i=document.body,s,n){super(t,i,s),this.radioParent=e,this.radioType=n}async[h](){try{await super[h](),this.initEventManager(),this.initVisibilityManager(),this.initValueManager(),this._bindMethods();let e=new MutationObserver(t=>{for(let i of t)if(Array.from(i.removedNodes).includes(this.element)){this[p](),e.disconnect();break}});e.observe(document.body,{childList:!0,subtree:!0}),f.instances.push(this),this.isLoaded=!0}catch(e){let t=e instanceof Error?e.message:String(e);throw new u.InitializationError(this,t)}}initEventManager(){this.eventManager=new w}initValueManager(){this.valueManager=new L(this),this._valueSync()}initVisibilityManager(){this.visibilityManager=new b(this.element)}[p](){super[p](),this.radioParent=void 0,this.radioType=void 0}};var L=class{value;checked=!1;element;noRadio;yesRadio;radioParent;isRadio=!1;radioType;constructor(e){e instanceof y?(this.noRadio=e.noRadio,this.yesRadio=e.yesRadio,this.radioParent=void 0):e instanceof d&&(this.isRadio=!0,this.noRadio=void 0,this.yesRadio=void 0,this.radioParent=e.radioParent,this.radioType=e.radioType),this.element=e.element}setValue(e){let t=this._validateValue(e);this.yesRadio instanceof d&&this.noRadio instanceof d?(this.yesRadio.element.checked=!!e,this.noRadio.element.checked=!e,this.value=e,this.element.checked=!!e,this.element.value=e):this.isRadio||this.element.type==="radio"?(this.element.checked=e,this.checked=e,this.value=e,this.radioParent?.updateValue()):(this.element.value=t,this.value=t)}async updateValue(e){e&&e.stopPropagation();let t=await this.getElementValue();if(this.value=t.value,t.checked!==void 0&&(this.checked=t.checked),this.radioParent instanceof y&&e&&e.type!=="manual-radio-sync"){switch(this.radioType){case"falsy":this.radioParent.yesRadio.setValue(!t),await this.radioParent.yesRadio.updateValue(new Event("manual-radio-sync"));break;case"truthy":this.radioParent.noRadio.setValue(!t),await this.radioParent.noRadio.updateValue(new Event("manual-radio-sync"));break}this.radioParent.updateValue()}}getElementValue(){return new Promise(e=>{let t=this.element,i=this.element;this.yesRadio instanceof d&&this.noRadio instanceof d&&e({value:this.yesRadio.checked,checked:this.yesRadio.checked});let s={value:null};switch(t.type){case"checkbox":case"radio":e({value:t.checked,checked:t.checked});break;case"select-multiple":e({value:Array.from(i.selectedOptions).map(n=>n.value)});break;case"select-one":e({value:i.value});break;case"number":e({value:t.value!==""?Number(t.value):null});break;default:{let n=t.value;this.element.classList.contains("decimal")&&(n=parseFloat(t.value.replace(/[$,]/g,"").trim())),s={value:n}}}s={...s,value:this._validateValue(s.value)},e(s)})}_validateValue(e){return typeof e=="boolean"||e==="true"||e==="false"?e===!0||e==="true":this.element instanceof HTMLSelectElement||this.element.type==="text"&&!this.element.classList.contains("decimal")||e===null||e===""||isNaN(Number(e))?e:Number(e)}clearValue(){try{let e=this.element;if(e.defaultValue="",e instanceof HTMLInputElement)switch(e.type.toLowerCase()){case"checkbox":case"radio":e.checked=!1,this.checked=!1,this.value=!1;break;case"number":e.value="",this.value=null;break;default:e.value="",this.value=null;break}else e instanceof HTMLSelectElement?e.multiple?(Array.from(e.options).forEach(t=>t.selected=!1),this.value=null):(e.selectedIndex=-1,this.value=null):e instanceof HTMLTextAreaElement?(e.value="",this.value=null):this.value=null}catch(e){let t=`Failed to clear values for element with target "${this}": ${e instanceof Error?e.message:String(e)}`;throw new Error(t)}}destroy(){this.value=null,this.checked=!1,this.element=null,this.noRadio=void 0,this.yesRadio=void 0,this.isRadio=!1}};var P=class extends M{input;options;buffer="";charAtSelection="";charBeforeSelection="";lengthOf0FormattedValue;digitRegex=/\d/;nonDigitRegex=/\D/g;thousandsRegex=/\B(?=(\d{3})+(?!\d))/g;separatorRegex;constructor(e,t={}){super(),this.input=e,this.options={prefix:t.prefix||"$",decimalPlaces:t.decimalPlaces??2,thousandsSeparator:t.thousandsSeparator||",",decimalSeparator:t.decimalSeparator||".",allowNegative:t.allowNegative??!0};let i=this.escapeRegExp(this.options.thousandsSeparator),s=this.escapeRegExp(this.options.decimalSeparator);this.separatorRegex=new RegExp(`[${i}${s}]`),this.onFocus=this.onFocus.bind(this),this.onInput=this.onInput.bind(this),this.onSelectionChange=this.onSelectionChange.bind(this),this.onBlur=this.onBlur.bind(this),this.lengthOf0FormattedValue=`0${this.options.decimalPlaces>0?this.options.decimalSeparator+"0".repeat(this.options.decimalPlaces):""}`.length,this.setupEventListeners(),this.input.value&&(this.buffer=this.input.value.replace(this.nonDigitRegex,"")),this.formatAndDisplay()}escapeRegExp(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}formatAndDisplay(){let e=Number(this.buffer||"0");this.input.value=this.formatNumber(e)}setupEventListeners(){this.input.addEventListener("focus",this.onFocus),this.input.addEventListener("input",this.onInput),this.input.addEventListener("selectionchange",this.onSelectionChange),this.input.addEventListener("blur",this.onBlur)}formatInput(){let e=this.input.value,t=this.input.selectionStart||0,i=e.length,s=new RegExp(`[^0-9${this.options.decimalSeparator}${this.options.allowNegative?"-":""}]`,"g"),n=e.replace(s,""),o=n.split(this.options.decimalSeparator);o.length>2&&(n=o[0]+this.options.decimalSeparator+o.slice(1).join("")),this.options.allowNegative&&n.indexOf("-")>0&&(n=n.replace(/-/g,""),n.charAt(0)!=="-"&&(n="-"+n));let l;n===""||n==="-"?l=0:l=parseFloat(n.replace(this.options.decimalSeparator,".")),isNaN(l)&&(l=0);let a=this.formatNumber(l);this.input.value=a;let c=t+(a.length-i);this.input.setSelectionRange(c,c)}formatNumber(e){let t=e/10**this.options.decimalPlaces,i=t<0,n=Math.abs(t).toFixed(this.options.decimalPlaces),[o,l]=n.split("."),a=o.replace(this.thousandsRegex,this.options.thousandsSeparator);return(i?"-":"")+this.options.prefix+a+(this.options.decimalPlaces>0?this.options.decimalSeparator+l:"")}onSelectionChange(e){let t=this.input.selectionStart;this.charAtSelection=this.input.value[t],this.charBeforeSelection=this.input.value[t-1]}onInput(e){let t=e,i=this.input.value,s=this.input.selectionStart??0,n=i.slice(0,s).replace(this.nonDigitRegex,"").length,o=n;switch(t.inputType){case"insertText":this.buffer=this.buffer.slice(0,n-1)+(t.data||"").replace(this.nonDigitRegex,"")+this.buffer.slice(n-1),o=n;break;case"deleteContentBackward":n>=0?this.separatorRegex.test(this.charBeforeSelection)?(this.buffer=this.buffer.slice(0,n-1)+this.buffer.slice(n),o=n-1):(this.buffer=this.buffer.slice(0,n)+this.buffer.slice(n+1),o=n):i===""&&(this.buffer="");break;case"deleteContentForward":n<this.buffer.length&&(this.buffer=this.buffer.slice(0,n)+this.buffer.slice(n+1));break;case"deleteWordBackward":case"deleteWordForward":this.buffer="",o=this.lengthOf0FormattedValue;break;default:this.buffer=i.replace(this.nonDigitRegex,""),o=this.buffer.length}let l=Number(this.buffer||"0"),a=this.formatNumber(l);this.input.value=a;let c=this.mapRawIndexToFormattedPosition(o,a);this.input.setSelectionRange(c,c)}mapRawIndexToFormattedPosition(e,t){let i=0;for(let s=0;s<t.length;s++)if(this.digitRegex.test(t[s])&&i++,i===e)return s+1;return t.length}onFocus(){setTimeout(()=>this.input.select(),0)}onBlur(){let e=Number(this.buffer||"0");if(this.input.value=this.formatNumber(e),e===0){this.buffer="";let t="0".repeat(this.options.decimalPlaces);this.input.value=`${this.options.prefix}0${this.options.decimalPlaces>0?this.options.decimalSeparator+t:""}`}}getNumericalValue(){return Number(this.buffer||"0")/10**this.options.decimalPlaces}setValue(e){let t=Math.round(Math.abs(e)*10**this.options.decimalPlaces);this.buffer=t.toString(),this.input.value=this.formatNumber(t)}destroy(){this.input.removeEventListener("focus",this.onFocus),this.input.removeEventListener("input",this.onInput),this.input.removeEventListener("selectionchange",this.onSelectionChange),this.input.removeEventListener("blur",this.onBlur)}};var y=class r extends f{isMasked=!1;yesRadio;noRadio;constructor(e,t=document.body,i){super(e,t,i)}async[h](){try{await super[h](),this.element.id&&this.element.querySelectorAll(`#${this.element.id} > input[type="radio"]`).length>0&&await this._attachRadioButtons(),this.initEventManager(),this.initVisibilityManager(),this.initValueManager(),this._bindMethods();let e=new MutationObserver(t=>{for(let i of t)if(Array.from(i.removedNodes).includes(this.element)){typeof this[p]=="function"&&this[p](),e.disconnect();break}});e.observe(document.body,{childList:!0,subtree:!0}),r.instances.push(this),this.isLoaded=!0}catch(e){let t=e instanceof Error?e.message:String(e);throw new u.InitializationError(this,t)}}initValueManager(){this.valueManager=new L(this),this._valueSync()}initVisibilityManager(){this.visibilityManager=new b(this.element)}initEventManager(){this.eventManager=new w}async _attachRadioButtons(){if(!this.element){console.error("'this.element' not found: cannot attach radio buttons for ",this.target);return}this.yesRadio=new d(this,'input[type="radio"][value="1"]',this.element,0,"truthy"),this.noRadio=new d(this,'input[type="radio"][value="0"]',this.element,0,"falsy"),await this.yesRadio[h](),await this.noRadio[h]()}clearValue(){this.yesRadio instanceof d&&this.noRadio instanceof d&&(this.yesRadio.clearValue(),this.noRadio.clearValue()),super.clearValue()}uncheckRadios(){return this.yesRadio instanceof f&&this.noRadio instanceof f?(this.yesRadio.element.checked=!1,this.noRadio.element.checked=!1):console.error("[SYNACT] Attempted to uncheck radios for an element that has no radios"),this}inputMask(e,t){if(this.isMasked)throw new Error(`You cannot apply multiple input masks to the same element. @${this.target}`);let i;switch(e){case"money":i=new P(this.element,t);break;case"phone":i=new R(this.element,t);break;default:throw new Error(`No type provided for 'inputMask()' at: ${this.target}`)}return this.valueManager.element=i.input,this.isMasked=!0,this}[p](){super[p](),this.yesRadio?.[p](),this.noRadio?.[p](),this.yesRadio=void 0,this.noRadio=void 0}};var T=class extends Array{hideAll(){return this.forEach(e=>e.hide()),this}showAll(){return this.forEach(e=>e.show()),this}};function D(r){let e=new T(...r);return new Proxy(e,{get(t,i,s){if(i in t)return Reflect.get(t,i,s);if(typeof i=="string")return t.find(n=>n.target.toString().replace(/[#\[\]]/g,"")===i||n.logicalName===i)}})}async function O(r,e={multiple:!1,root:document.body,timeoutMs:0}){try{if(typeof e!="object")throw new TypeError(`'options' must be of type 'object'. Received type: '${typeof e}'`);X(e);let{multiple:t=!1,root:i=document.body,timeoutMs:s=0}=e;if(typeof t=="function"?t():t){if(typeof r!="string")throw new TypeError(`'target' must be of type 'string' if 'multiple' is set to 'true'. Received type: '${typeof r}'`);let l=await E(r,i,!0,s),a=await Promise.all(l.map(async c=>{let C=new y(c,i,s);return await C[h](),new Proxy(C,W())}));return D(a)}let o=new y(r,i,s);return await o[h](),new Proxy(o,W())}catch(t){throw t instanceof Error?t:new Error("Failed to get DOM Node by target: "+r)}}function X(r){let{multiple:e=!1,root:t=document.body,timeoutMs:i=0}=r;if(typeof e!="boolean"&&typeof e!="function")throw new TypeError(`'multiple' must be of type 'boolean' or 'function'. Received type: '${typeof e}'`);if(typeof e=="function"){let s=e();if(typeof s!="boolean")throw new TypeError(`'multiple' function must return a boolean. Received type: '${typeof s}'`)}if(!(t instanceof HTMLElement))throw new TypeError(`'root' must be of type 'HTMLElement'. Received type: '${typeof t}'`);if(typeof i!="number")throw new TypeError(`'timeout' must be of type 'number'. Received type: '${typeof i}'`)}function W(){return{get:(r,e)=>{if(e.toString().startsWith("_"))return;let t=r[e];return typeof t=="function"&&e!=="onceLoaded"?(...i)=>(r.onceLoaded(()=>t.apply(r,i)),r):t}}}async function J(r){try{let e=await H.getRecord("systemforms",r),{formxml:t}=e,s=new DOMParser().parseFromString(t,"application/xml"),n=z(s.getElementsByTagName("control")),o=z(s.getElementsByTagName("section")),l=z(s.getElementsByTagName("tab")),a=await Promise.all([...n,...o,...l]);return D(a.filter(c=>c!==null))}catch(e){throw e instanceof Error?(console.error(e.message),e):(console.error(e),new Error(String(e)))}}function z(r){return Array.from(r).map(e=>{let t=K(e.tagName),i=e.getAttribute(t);if(!i)return null;let s=Q(e.tagName,i);return s?O(s).catch(n=>(console.warn(`Failed to create a reference to the form field: ${i}`,n),null)):null}).filter(Boolean)}function K(r){return r==="control"?"id":r==="tab"||r==="section"?"name":"id"}function Q(r,e){return r==="control"?`#${e}`:r==="tab"||r==="section"?`[data-name="${e}"]`:null}var x=class extends HTMLElement{element;constructor(){if(!document)throw new Error("Cannot instantiate 'LoadingSpinner': No DOM Found");super(),this.id="loader",this.classList.add("loader-overlay","hidden"),this.element=document.createElement("div"),this.element.classList.add("spinner-border","text-light"),this.element.role="status",this.appendChild(this.element);let e=document.createElement("span");e.classList.add("visually-hidden"),e.textContent="Loading...",this.element.appendChild(e),document.body.appendChild(this)}hide(){this.classList.add("hidden")}show(){this.classList.remove("hidden")}},Y=`loading-${crypto.randomUUID()}`;customElements.define(Y,x);export{H as API,x as LoadingSpinner,J as bindForm,O as get,E as waitFor};
|
|
2
|
+
function g(r){let e=$.Deferred();return shell.getTokenDeferred().done(function(t){r.headers?r.headers.__RequestVerificationToken=t:$.extend(r,{headers:{__RequestVerificationToken:t}}),$.ajax(r).done(function(i,s,n){validateLoginSession(i,s,n,e.resolve)}).fail(e.reject)}).fail(function(){e.rejectWith(this,arguments)}),e.promise()}var S=class{static createRecord(e,t){return new Promise((i,s)=>{g({type:"POST",url:`/_api/${e}`,data:JSON.stringify(t),contentType:"application/json",success:function(n,o,l){i(l.getResponseHeader("entityid"))},error:n=>{s(n)}})})}static getRecord(e,t,i){return new Promise((s,n)=>{let o=`/_api/${e}(${t})${i?`${i}`:""}`;g({type:"GET",url:o,success:s,error:n})})}static request(e,t){return new Promise((i,s)=>{let n=`/_api/${e}`;g({url:n,success:i,error:s,...t})})}static getMultiple(e,t){return new Promise((i,s)=>{let n=`/_api/${e}${t?`?${t}`:""}`;g({type:"GET",url:n,success:function(o){i(o.value)},error:s})})}static updateRecord(e,t,i){return new Promise((s,n)=>{let o=`/_api/${e}(${t})`;g({type:"PATCH",url:o,data:JSON.stringify(i),success:s,error:n})})}},H=S;var b=class{defaultVisibility;set defaultDisplay(e){this.defaultVisibility=e}constructor(e){if(this.visibilityController=e,e.tagName==="TABLE"){let i=e.closest("fieldset");i&&(this.visibilityController=i)}if(["SPAN","INPUT","TEXTAREA","SELECT","TABLE"].includes(e.tagName)){let i=e.closest("td");i&&(this.visibilityController=i)}this.defaultVisibility=this.visibilityController.style.display}hide(){this.visibilityController.style.display="none"}show(){this.visibilityController.style.display=this.defaultVisibility}toggleVisibility(e){e?this.show():this.hide()}getVisibility(){return window.getComputedStyle(this.visibilityController).display!=="none"&&window.getComputedStyle(this.visibilityController).visibility!=="hidden"&&this.visibilityController.getBoundingClientRect().height>0&&this.visibilityController.getBoundingClientRect().width>0}destroy(){this.visibilityController=null,this.defaultVisibility=null}};var N={CHECKBOX:"click",RADIO:"click",SELECT:"change",TEXT:"keyup",DEFAULT:"input"};var h=Symbol("init"),p=Symbol("destroy");var v=class extends HTMLElement{flyoutContent;icon;observers=[];constructor(e,t){if(super(),typeof e!="string")throw new Error(`argument "titleString" must be of type "string". Received: "${typeof e}"`);if(t&&typeof t!="object")throw new Error(`argument "iconStyle" must be of type "object". Received: "${typeof t}"`);this.classList.add("info-icon"),this.icon=document.createElement("i"),this.icon.classList.add("fa","fa-solid","fa-info-circle"),this.icon.setAttribute("aria-label","Info"),this.icon.style.cursor="pointer",this.flyoutContent=document.createElement("div"),this.flyoutContent.innerHTML=e,this.flyoutContent.classList.add("flyout-content"),this.appendChild(this.icon),this.appendChild(this.flyoutContent),t&&Object.assign(this.icon.style,t),this.handleClick=this.handleClick.bind(this),this.handleResize=this.handleResize.bind(this),this.handleTouchStart=this.handleTouchStart.bind(this),this.handleMouseEnter=this.handleMouseEnter.bind(this),this.handleMouseLeave=this.handleMouseLeave.bind(this),this.handleScroll=this.handleScroll.bind(this),this.flyoutContent.style.minWidth=this.getDesiredWidth(),this.flyoutContent.style.display="none",this.attachEventListeners(),this.setupObservers()}attachEventListeners(){document.body.addEventListener("click",this.handleClick),self.addEventListener("resize",this.handleResize),this.icon.addEventListener("touchstart",this.handleTouchStart),this.addEventListener("mouseenter",this.handleMouseEnter),this.addEventListener("mouseleave",this.handleMouseLeave),self.addEventListener("scroll",this.handleScroll)}setupObservers(){let e=new MutationObserver(i=>{for(let s of i)for(let n of Array.from(s.removedNodes))if(n===this){this.destroy();return}});e.observe(document,{childList:!0,subtree:!0,attributes:!1});let t=new MutationObserver(()=>this.updateFlyoutWidth);t.observe(document,{childList:!0,subtree:!0,attributes:!1}),this.observers.push(e,t)}getDesiredWidth(){let e=self.innerWidth;return`${Math.min(e-40,600)}px`}positionFlyout(){this.flyoutContent.style.display="block";let e=this.icon.getBoundingClientRect(),t=this.flyoutContent.getBoundingClientRect(),i=self.innerHeight,n=e.bottom-5;n+t.height>i&&(n=e.top-t.height),this.flyoutContent.style.top=`${n}px`}updateFlyoutWidth(){this.flyoutContent.style.minWidth=this.getDesiredWidth()}handleClick(e){this.contains(e.target)||(this.flyoutContent.style.display="none")}handleResize(e){this.flyoutContent.style.minWidth=this.getDesiredWidth()}handleTouchStart(){this.flyoutContent.style.display=this.flyoutContent.style.display==="block"?"none":"block",this.flyoutContent.style.display==="block"&&this.positionFlyout()}handleMouseEnter(e){this.positionFlyout()}handleMouseLeave(e){let t=e.relatedTarget;this.contains(t)||(this.flyoutContent.style.display="none")}handleScroll(){let e=this.flyoutContent.style.display;e!=="none"&&(this.positionFlyout(),this.flyoutContent.style.display=e)}destroy(){document.body.removeEventListener("click",this.handleClick),self.removeEventListener("resize",this.handleResize),this.icon.removeEventListener("touchstart",this.handleTouchStart),this.removeEventListener("mouseenter",this.handleMouseEnter),this.removeEventListener("mouseleave",this.handleMouseLeave),self.removeEventListener("scroll",this.handleScroll),this.observers.forEach(e=>e.disconnect())}},U=`info-icon-${crypto.randomUUID()}`;customElements.define(U,v);function E(r,e=document,t=!1,i){return new Promise((s,n)=>{if(t){let o,l=[],a=new Set;if(i<1)return s(Array.from(e.querySelectorAll(r)));let c=new MutationObserver(()=>{Array.from(e.querySelectorAll(r)).forEach(V=>{a.has(V)||(a.add(V),l.push(V))}),clearTimeout(o),o=setTimeout(()=>{l.length>0?(c.disconnect(),s(l)):n(new Error(`No elements found with target: "${r}" within ${i/1e3} seconds. If the element you are expecting has not loaded yet, consider raising your timeout.`))},i)});c.observe(e,{childList:!0,subtree:!0,attributes:!1})}else{let o=new MutationObserver(()=>{let c=e.querySelector(r);c&&(clearTimeout(l),o.disconnect(),s(c))}),l=setTimeout(()=>{o.disconnect(),n(new Error(`Element not found by target: "${r}" within ${i/1e3} second. If the element you are expecting has not loaded yet, consider raising your timeout.`))},i),a=e.querySelector(r);if(a)return clearTimeout(l),s(a);o.observe(e,{subtree:!0,attributes:!0,childList:!0})}})}var m=class extends Error{node;constructor(e,t){super(t),this.node=e,Object.setPrototypeOf(this,new.target.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}},k=class extends m{constructor(e,t){super(e,`There was an error initializing a DOMNodeReference for target: ${e.target}, :: ${t}`)}},I=class extends m{constructor(e){super(e,`The targeted DOM element was not found: ${e.target}`)}},F=class extends m{constructor(e){super(e,"Page_Validators could not be found")}},A=class extends m{constructor(e){super(e,`Error applying business rule to target: ${e.target}`)}},_=class extends m{constructor(e){super(e,"Self-referential dependency found. A DOMNodeReference cannot depend on itself")}},B=class extends m{constructor(e){super(e,`No label could be found for the target: ${e.target}`)}},q=class extends m{constructor(e,t,i,s,n){let o=s.join(" or ");super(e,`${t} expects ${i} to be of type ${o}. Received: ${n===null?"null":typeof n}`)}},G={NodeNotFoundError:I,InitializationError:k,Page_ValidatorsNotFoundError:F,BusinessRuleError:A,SelfReferenceError:_,LabelNotFoundError:B,IncorrectParameterError:q},u=G;import j from"DOMPurify";var f=class r{static instances=[];target;logicalName;root;timeoutMs;isLoaded;get value(){return this.valueManager.value}set value(e){this.valueManager.setValue(e)}get checked(){return this.valueManager.checked}set defaultDisplay(e){this.visibilityManager.defaultDisplay=e}visibilityManager;valueManager;eventManager;constructor(e,t=document.body,i){this.target=e,this.logicalName=this._extractLogicalName(e),this.root=t,this.timeoutMs=i,this.isLoaded=!1}async[h](){if(this.target instanceof HTMLElement?this.element=this.target:this.element=await E(this.target,this.root,!1,this.timeoutMs),!this.element)throw new u.NodeNotFoundError(this)}_extractLogicalName(e){if(typeof e!="string")return"";let t=e.match(/\[([^\]]+)\]/);if(!t)return e.replace(/[#\[\]]/g,"");let i=t[1];return(i.match(/["']([^"']+)["']/)?.[1]||i).replace(/[#\[\]]/g,"")}_valueSync(){if(!this._isValidFormElement(this.element))return;this.updateValue();let e=this._determineEventType();this.eventManager.registerDOMEventListener(this.element,e,this.updateValue.bind(this)),this._isDateInput()&&this._dateSync(this.element)}_determineEventType(){return this.element instanceof HTMLSelectElement?"change":this.element instanceof HTMLTextAreaElement?"keyup":this.element instanceof HTMLInputElement?N[this.element.type.toUpperCase()]||N.DEFAULT:N.DEFAULT}_isDateInput(){return this.element instanceof HTMLInputElement&&this.element.dataset.type==="date"}_isValidFormElement(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSpanElement||e instanceof HTMLButtonElement||e instanceof HTMLFieldSetElement}async _dateSync(e){let t=e.parentElement;if(!t)throw new DOMException("Date input must have a parent element");let i=await E("[data-date-format]",t,!1,1500);this.valueManager.element=i,this.eventManager.registerDOMEventListener(i,"select",this.updateValue.bind(this))}_bindMethods(){let e=Object.getPrototypeOf(this);for(let t of Object.getOwnPropertyNames(e)){let i=this[t];t!=="constructor"&&typeof i=="function"&&(this[t]=i.bind(this))}}[p](){this.isLoaded=!1,this.value=null,this.eventManager.destroy(),this.eventManager=null,this.visibilityManager.destroy(),this.visibilityManager=null,this.valueManager.destroy(),this.valueManager=null}async updateValue(e){e&&!e.isTrusted||(await this.valueManager.updateValue(e),this.triggerDependentsHandlers())}triggerDependentsHandlers(){this.eventManager.dispatchDependencyHandlers()}on(e,t){if(typeof t!="function")throw new u.IncorrectParameterError(this,"on","eventHandler",["function"],typeof t);let i=t;return this.eventManager.registerDOMEventListener(this.element,e,i.bind(this)),this}hide(){return this.visibilityManager.hide(),this}show(){return this.visibilityManager.show(),this}toggleVisibility(e){let t=e instanceof Function?e.call(this):e;return this.visibilityManager.toggleVisibility(t),this}setValue(e){return e instanceof Function&&(e=e()),this.valueManager.setValue(e),this}disable(){return this.element.disabled=!0,this}clearValue(){this.valueManager.clearValue(),this._getChildren()&&this.callAgainstChildrenInputs(e=>e.clearValue())}_getChildren(){let t=Array.from(this.element.querySelectorAll("input, select, textarea")).map(s=>s.id),i=r.instances.filter(s=>t.includes(s.element.id));return i.length>0?i:null}callAgainstChildrenInputs(e){let t=this._getChildren();if(!t){console.error("No child inputs found for target: ",this);return}for(let i of t)e(i)}enable(){return this.element.disabled=!1,this}prepend(...e){return this.element.prepend(...e),this}append(...e){return this.element.append(...e),this}before(...e){return this.element.before(...e),this}after(...e){return this.element.after(...e),this}getLabel(){let e=document.querySelector(`#${this.element.id}_label`)||null;if(!e)throw new u.LabelNotFoundError(this);return e}addLabelTooltip(e,t){let i=j.sanitize(e);return this.getLabel()?.append(new v(i,t||void 0)),this}addTooltip(e,t){let i=j.sanitize(e);return this.append(new v(i,t||void 0)),this}set innerHTML(e){let t=j.sanitize(e);this.element.innerHTML=t}remove(){return this.element.remove(),this}setStyle(e){if(e===null||typeof e!="object")throw new u.IncorrectParameterError(this,"setStyle","options",["Partial<CSSStyleDeclaration>"],typeof e);return Object.entries(e).forEach(([t,i])=>{i!==void 0&&(this.element.style[t]=i)}),this}applyBusinessRule(e,t){try{e.setRequirements&&this._setupRequirementsValidator(e.setRequirements());let i=this._createBusinessRuleHandler(e);return i(),t.length&&this._configureDependencyTracking(i,t),this}catch(i){throw i instanceof Error?i:new u.BusinessRuleError(this)}}_setupRequirementsValidator(e){let{isRequired:t,isValid:i}=e;if(typeof Page_Validators>"u")throw new u.Page_ValidatorsNotFoundError(this);let s=()=>!0;t&&i?s=()=>{let n=t.call(this),o=this.visibilityManager.getVisibility();return!n||o&&i.call(this,n)}:i?s=()=>this.visibilityManager.getVisibility()&&i.call(this,!1):t&&(s=()=>this.visibilityManager.getVisibility()&&t.call(this)),this._createValidator(s)}_createBusinessRuleHandler(e){return()=>{let t=!1;if(e.setVisibility){let s=e.setVisibility.call(this);t=!s,this.toggleVisibility(s)}if(e.setRequirements&&e.setRequirements().isRequired){let{isRequired:i}=e.setRequirements();this.setRequiredLevel(i.call(this))}if(e.setValue){let{condition:i,value:s}=e.setValue();if(i.call(this)){let n=s instanceof Function?s():s;this.setValue.call(this,n)}}e.setDisabled&&(e.setDisabled.call(this)?this.disable():this.enable()),t&&!e.setValue&&this.clearValue(),this.triggerDependentsHandlers()}}_createValidator(e){let t=(()=>{let n=this.getLabel();if(!n)throw new u.LabelNotFoundError(this);return n=n.innerHTML,n.length>50&&(n=n.substring(0,50)+"..."),n})(),i=`${this.element.id}Validator`,s=document.createElement("span");if(s.style.display="none",s.id=i,Object.assign(s,{controltovalidate:this.element.id,errormessage:`<a href='#${this.element.id}_label'>${t} is a required field</a>`,evaluationfunction:e.bind(this)}),Page_Validators==null)throw new u.Page_ValidatorsNotFoundError(this);Page_Validators.push(s)}_configureDependencyTracking(e,t){if(t.length<1){console.error(`powerpagestoolkit: No dependencies specified for ${this.element.id}. Include all required nodes in the dependency array for proper tracking.`);return}t.forEach(i=>{if(!i||!(i instanceof r))throw new TypeError("Each dependency must be a valid DOMNodeReference instance");if(i.logicalName===this.logicalName)throw new u.SelfReferenceError(this);i.eventManager.registerDependent(this,e.bind(this))})}setRequiredLevel(e){return e instanceof Function?(e.call(this)?this.getLabel()?.classList.add("required-field"):this.getLabel()?.classList.remove("required-field"),this):(e?this.getLabel()?.classList.add("required-field"):this.getLabel()?.classList.remove("required-field"),this)}onceLoaded(e){if(this.isLoaded){e(this);return}if(this.target instanceof HTMLElement){e(this);return}let t=new MutationObserver(function(){document.querySelector(this.target)&&(t.disconnect(),this.isLoaded=!0,e(this))}.bind(this));this.eventManager.registerObserver(t,{nodeToObserve:document.body,options:{subtree:!0,childList:!0}})}};var M=class{constructor(){}onFocus(){setTimeout(()=>this.input.select(),0)}onBlur(){this.formatInput()}setValue(e){this.input.value=String(e)}};var R=class extends M{input;options;constructor(e,t={}){super(),this.input=e,this.options={format:t.format||"(xxx) xxx-xxxx",countryCode:t.countryCode||"",countryCodeFormat:t.countryCodeFormat||"+"},this.onFocus=this.onFocus.bind(this),this.formatInput=this.formatInput.bind(this),this.onBlur=this.onBlur.bind(this),this.setupEventListeners(),setTimeout(()=>{this.formatInput()},0)}setupEventListeners(){this.input.addEventListener("focus",this.onFocus),this.input.addEventListener("input",this.formatInput),this.input.addEventListener("blur",this.onBlur)}formatInput(){let e=this.input.value,t=this.input.selectionStart||0,i=e.length,s=e.replace(/\D/g,""),n=this.formatPhoneNumber(s);this.input.value=n;let o=Math.min(t+(n.length-i),n.length);this.input.setSelectionRange(o,o)}formatPhoneNumber(e){if(!e)return"";let t=e,i="";if(this.options.countryCode){let a=this.options.countryCode.length;e.length>a?(i=e.substring(0,a),t=e.substring(a)):(i=e,t="")}let s="";if(i)switch(this.options.countryCodeFormat){case"+":s=`+${i} `;break;case"()":s=`(${i}) `;break;case"00":s=`00${i} `;break;default:s=`+${i} `}let n=this.options.format,o=0;for(let a=0;a<n.length&&o<t.length;a++)n[a]==="x"&&(n=n.substring(0,a)+t[o++]+n.substring(a+1));n=n.replace(/x/g,"");let l=n.split("").findIndex((a,c)=>!/\d/.test(a)&&n.substring(c).indexOf("x")===-1&&n.substring(c).replace(/[\s\-()]/g,"").length===0);return l!==-1&&(n=n.substring(0,l)),s+n}onFocus(){setTimeout(()=>this.input.select(),0)}onBlur(){this.formatInput();let e=this.getDigits(),t=this.options.countryCode?7+this.options.countryCode.length:7;e.length<t}getDigits(){return this.input.value.replace(/\D/g,"")}getCountryCode(){if(!this.options.countryCode)return"";let e=this.getDigits(),t=this.options.countryCode.length;return e.length>=t?e.substring(0,t):e}getPhoneDigits(){if(!this.options.countryCode)return this.getDigits();let e=this.getDigits(),t=this.options.countryCode.length;return e.length>t?e.substring(t):""}setValue(e){let t=e.replace(/\D/g,"");this.input.value=this.formatPhoneNumber(t)}isValid(){let e=this.getPhoneDigits(),t=this.getCountryCode();return(!this.options.countryCode||t.length===this.options.countryCode.length)&&e.length>=10}destroy(){this.input.removeEventListener("focus",this.onFocus),this.input.removeEventListener("input",this.formatInput),this.input.removeEventListener("blur",this.onBlur)}};var w=class{events=new Map;listeners=new Map;dependencyHandlers=new Set;observers=[];boundListeners=[];constructor(){}dispatchDependencyHandlers(){for(let[e,t]of this.dependencyHandlers)t.call(e)}registerDependent(e,t){try{return this.dependencyHandlers.add([e,t]),"success"}catch{return new Error(`Failed register dependant: ${e.target}`)}}registerEvent(e,t){return this.events.has(e)?(console.error("Event registration has already been defined for: ",e),new Error(`Event registration has already been defined for: ${e}`)):(this.listeners.set(e,new Set),this.events.set(e,t),"success")}registerListener(e,t){if(this.events.has(e)){let i=this.listeners.get(e)??new Set;return i.add(t),this.listeners.set(e,i),"success"}else return console.error("No event registration found for: ",e),new Error(`No event registration found for: ${e}`)}emit(e,...t){if(this.events.has(e)){let i=this.events.get(e),s=this.listeners.get(e);if(!s)return;for(let n of s)i.call(n,...t)}else console.error("Event not found in EventRegistry: ",e)}stopListening(e){for(let[t,i]of this.listeners)i.has(e)&&i.delete(e)}registerObserver(e,t){let{nodeToObserve:i,options:s}=t;e.observe(i,s),this.observers.push(e)}registerDOMEventListener(e,t,i){e.addEventListener(t,i),this.boundListeners.push({element:e,handler:i,event:t})}destroy(){this.boundListeners?.forEach(e=>{e.element?.removeEventListener(e.event,e.handler)}),this.boundListeners=[],this.observers?.forEach(e=>{e.disconnect()}),this.observers=[],this.events.clear(),this.dependencyHandlers.clear(),this.listeners.clear()}};var d=class extends f{radioType;constructor(e,t,i=document.body,s,n){super(t,i,s),this.radioParent=e,this.radioType=n}async[h](){try{await super[h](),this.initEventManager(),this.initVisibilityManager(),this.initValueManager(),this._bindMethods();let e=new MutationObserver(t=>{for(let i of t)if(Array.from(i.removedNodes).includes(this.element)){this[p](),e.disconnect();break}});e.observe(document.body,{childList:!0,subtree:!0}),f.instances.push(this),this.isLoaded=!0}catch(e){let t=e instanceof Error?e.message:String(e);throw new u.InitializationError(this,t)}}initEventManager(){this.eventManager=new w}initValueManager(){this.valueManager=new L(this),this._valueSync()}initVisibilityManager(){this.visibilityManager=new b(this.element)}[p](){super[p](),this.radioParent=void 0,this.radioType=void 0}};var L=class{value;checked=!1;element;noRadio;yesRadio;radioParent;isRadio=!1;radioType;constructor(e){e instanceof y?(this.noRadio=e.noRadio,this.yesRadio=e.yesRadio,this.radioParent=void 0):e instanceof d&&(this.isRadio=!0,this.noRadio=void 0,this.yesRadio=void 0,this.radioParent=e.radioParent,this.radioType=e.radioType),this.element=e.element}setValue(e){let t=this._validateValue(e);this.yesRadio instanceof d&&this.noRadio instanceof d?(this.yesRadio.element.checked=!!e,this.noRadio.element.checked=!e,this.value=e,this.element.checked=!!e,this.element.value=e):this.isRadio||this.element.type==="radio"?(this.element.checked=e,this.checked=e,this.value=e,this.radioParent?.updateValue()):(this.element.value=t,this.value=t)}async updateValue(e){e&&e.stopPropagation();let t=await this.getElementValue();if(this.value=t.value,t.checked!==void 0&&(this.checked=t.checked),this.radioParent instanceof y&&e&&e.type!=="manual-radio-sync"){switch(this.radioType){case"falsy":this.radioParent.yesRadio.setValue(!t),await this.radioParent.yesRadio.updateValue(new Event("manual-radio-sync"));break;case"truthy":this.radioParent.noRadio.setValue(!t),await this.radioParent.noRadio.updateValue(new Event("manual-radio-sync"));break}this.radioParent.updateValue()}}getElementValue(){return new Promise(e=>{let t=this.element,i=this.element;this.yesRadio instanceof d&&this.noRadio instanceof d&&e({value:this.yesRadio.checked,checked:this.yesRadio.checked});let s={value:null};switch(t.type){case"checkbox":case"radio":e({value:t.checked,checked:t.checked});break;case"select-multiple":e({value:Array.from(i.selectedOptions).map(n=>n.value)});break;case"select-one":e({value:i.value});break;case"number":e({value:t.value!==""?Number(t.value):null});break;default:{let n=t.value;this.element.classList.contains("decimal")&&(n=parseFloat(t.value.replace(/[$,]/g,"").trim())),s={value:n}}}s={...s,value:this._validateValue(s.value)},e(s)})}_validateValue(e){return typeof e=="boolean"||e==="true"||e==="false"?e===!0||e==="true":this.element instanceof HTMLSelectElement||this.element.type==="text"&&!this.element.classList.contains("decimal")||e===null||e===""||isNaN(Number(e))?e:Number(e)}clearValue(){try{let e=this.element;if(e.defaultValue="",e instanceof HTMLInputElement)switch(e.type.toLowerCase()){case"checkbox":case"radio":e.checked=!1,this.checked=!1,this.value=!1;break;case"number":e.value="",this.value=null;break;default:e.value="",this.value=null;break}else e instanceof HTMLSelectElement?e.multiple?(Array.from(e.options).forEach(t=>t.selected=!1),this.value=null):(e.selectedIndex=-1,this.value=null):e instanceof HTMLTextAreaElement?(e.value="",this.value=null):this.value=null}catch(e){let t=`Failed to clear values for element with target "${this}": ${e instanceof Error?e.message:String(e)}`;throw new Error(t)}}destroy(){this.value=null,this.checked=!1,this.element=null,this.noRadio=void 0,this.yesRadio=void 0,this.isRadio=!1}};var P=class extends M{input;options;buffer="";charAtSelection="";charBeforeSelection="";lengthOf0FormattedValue;digitRegex=/\d/;nonDigitRegex=/\D/g;thousandsRegex=/\B(?=(\d{3})+(?!\d))/g;separatorRegex;constructor(e,t={}){super(),this.input=e,this.options={prefix:t.prefix||"$",decimalPlaces:t.decimalPlaces??2,thousandsSeparator:t.thousandsSeparator||",",decimalSeparator:t.decimalSeparator||".",allowNegative:t.allowNegative??!0};let i=this.escapeRegExp(this.options.thousandsSeparator),s=this.escapeRegExp(this.options.decimalSeparator);this.separatorRegex=new RegExp(`[${i}${s}]`),this.onFocus=this.onFocus.bind(this),this.onInput=this.onInput.bind(this),this.onSelectionChange=this.onSelectionChange.bind(this),this.onBlur=this.onBlur.bind(this),this.lengthOf0FormattedValue=`0${this.options.decimalPlaces>0?this.options.decimalSeparator+"0".repeat(this.options.decimalPlaces):""}`.length,this.setupEventListeners(),this.input.value&&(this.buffer=this.input.value.replace(this.nonDigitRegex,"")),this.formatAndDisplay()}escapeRegExp(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}formatAndDisplay(){let e=Number(this.buffer||"0");this.input.value=this.formatNumber(e)}setupEventListeners(){this.input.addEventListener("focus",this.onFocus),this.input.addEventListener("input",this.onInput),this.input.addEventListener("selectionchange",this.onSelectionChange),this.input.addEventListener("blur",this.onBlur)}formatInput(){let e=this.input.value,t=this.input.selectionStart||0,i=e.length,s=new RegExp(`[^0-9${this.options.decimalSeparator}${this.options.allowNegative?"-":""}]`,"g"),n=e.replace(s,""),o=n.split(this.options.decimalSeparator);o.length>2&&(n=o[0]+this.options.decimalSeparator+o.slice(1).join("")),this.options.allowNegative&&n.indexOf("-")>0&&(n=n.replace(/-/g,""),n.charAt(0)!=="-"&&(n="-"+n));let l;n===""||n==="-"?l=0:l=parseFloat(n.replace(this.options.decimalSeparator,".")),isNaN(l)&&(l=0);let a=this.formatNumber(l);this.input.value=a;let c=t+(a.length-i);this.input.setSelectionRange(c,c)}formatNumber(e){let t=e/10**this.options.decimalPlaces,i=t<0,n=Math.abs(t).toFixed(this.options.decimalPlaces),[o,l]=n.split("."),a=o.replace(this.thousandsRegex,this.options.thousandsSeparator);return(i?"-":"")+this.options.prefix+a+(this.options.decimalPlaces>0?this.options.decimalSeparator+l:"")}onSelectionChange(e){let t=this.input.selectionStart;this.charAtSelection=this.input.value[t],this.charBeforeSelection=this.input.value[t-1]}onInput(e){let t=e,i=this.input.value,s=this.input.selectionStart??0,n=i.slice(0,s).replace(this.nonDigitRegex,"").length,o=n;switch(t.inputType){case"insertText":this.buffer=this.buffer.slice(0,n-1)+(t.data||"").replace(this.nonDigitRegex,"")+this.buffer.slice(n-1),o=n;break;case"deleteContentBackward":n>=0?this.separatorRegex.test(this.charBeforeSelection)?(this.buffer=this.buffer.slice(0,n-1)+this.buffer.slice(n),o=n-1):(this.buffer=this.buffer.slice(0,n)+this.buffer.slice(n+1),o=n):i===""&&(this.buffer="");break;case"deleteContentForward":n<this.buffer.length&&(this.buffer=this.buffer.slice(0,n)+this.buffer.slice(n+1));break;case"deleteWordBackward":case"deleteWordForward":this.buffer="",o=this.lengthOf0FormattedValue;break;default:this.buffer=i.replace(this.nonDigitRegex,""),o=this.buffer.length}let l=Number(this.buffer||"0"),a=this.formatNumber(l);this.input.value=a;let c=this.mapRawIndexToFormattedPosition(o,a);this.input.setSelectionRange(c,c)}mapRawIndexToFormattedPosition(e,t){let i=0;for(let s=0;s<t.length;s++)if(this.digitRegex.test(t[s])&&i++,i===e)return s+1;return t.length}onFocus(){setTimeout(()=>this.input.select(),0)}onBlur(){let e=Number(this.buffer||"0");if(this.input.value=this.formatNumber(e),e===0){this.buffer="";let t="0".repeat(this.options.decimalPlaces);this.input.value=`${this.options.prefix}0${this.options.decimalPlaces>0?this.options.decimalSeparator+t:""}`}}getNumericalValue(){return Number(this.buffer||"0")/10**this.options.decimalPlaces}setValue(e){let t=Math.round(Math.abs(e)*10**this.options.decimalPlaces);this.buffer=t.toString(),this.input.value=this.formatNumber(t)}destroy(){this.input.removeEventListener("focus",this.onFocus),this.input.removeEventListener("input",this.onInput),this.input.removeEventListener("selectionchange",this.onSelectionChange),this.input.removeEventListener("blur",this.onBlur)}};var y=class r extends f{isMasked=!1;yesRadio;noRadio;constructor(e,t=document.body,i){super(e,t,i)}async[h](){try{await super[h](),this.element.id&&this.element.querySelectorAll(`#${this.element.id} > input[type="radio"]`).length>0&&await this._attachRadioButtons(),this.initEventManager(),this.initVisibilityManager(),this.initValueManager(),this._bindMethods();let e=new MutationObserver(t=>{for(let i of t)if(Array.from(i.removedNodes).includes(this.element)){typeof this[p]=="function"&&this[p](),e.disconnect();break}});e.observe(document.body,{childList:!0,subtree:!0}),r.instances.push(this),this.isLoaded=!0}catch(e){let t=e instanceof Error?e.message:String(e);throw new u.InitializationError(this,t)}}initValueManager(){this.valueManager=new L(this),this._valueSync()}initVisibilityManager(){this.visibilityManager=new b(this.element)}initEventManager(){this.eventManager=new w}async _attachRadioButtons(){if(!this.element){console.error("'this.element' not found: cannot attach radio buttons for ",this.target);return}this.yesRadio=new d(this,'input[type="radio"][value="1"]',this.element,0,"truthy"),this.noRadio=new d(this,'input[type="radio"][value="0"]',this.element,0,"falsy"),await this.yesRadio[h](),await this.noRadio[h]()}clearValue(){this.yesRadio instanceof d&&this.noRadio instanceof d&&(this.yesRadio.clearValue(),this.noRadio.clearValue()),super.clearValue()}uncheckRadios(){return this.yesRadio instanceof f&&this.noRadio instanceof f?(this.yesRadio.element.checked=!1,this.noRadio.element.checked=!1):console.error("[SYNACT] Attempted to uncheck radios for an element that has no radios"),this}inputMask(e,t){if(this.isMasked)throw new Error(`You cannot apply multiple input masks to the same element. @${this.target}`);let i;switch(e){case"money":i=new P(this.element,t);break;case"phone":i=new R(this.element,t);break;default:throw new Error(`No type provided for 'inputMask()' at: ${this.target}`)}return this.valueManager.element=i.input,this.isMasked=!0,this}[p](){super[p](),this.yesRadio?.[p](),this.noRadio?.[p](),this.yesRadio=void 0,this.noRadio=void 0}};var T=class extends Array{hideAll(){return this.forEach(e=>e.hide()),this}showAll(){return this.forEach(e=>e.show()),this}};function D(r){let e=new T(...r);return new Proxy(e,{get(t,i,s){if(i in t)return Reflect.get(t,i,s);if(typeof i=="string")return t.find(n=>n.target.toString().replace(/[#\[\]]/g,"")===i||n.logicalName===i)}})}async function O(r,e={multiple:!1,root:document.body,timeoutMs:0}){try{if(typeof e!="object")throw new TypeError(`'options' must be of type 'object'. Received type: '${typeof e}'`);X(e);let{multiple:t=!1,root:i=document.body,timeoutMs:s=0}=e;if(typeof t=="function"?t():t){if(typeof r!="string")throw new TypeError(`'target' must be of type 'string' if 'multiple' is set to 'true'. Received type: '${typeof r}'`);let l=await E(r,i,!0,s),a=await Promise.all(l.map(async c=>{let C=new y(c,i,s);return await C[h](),new Proxy(C,W())}));return D(a)}let o=new y(r,i,s);return await o[h](),new Proxy(o,W())}catch(t){throw t instanceof Error?t:new Error("Failed to get DOM Node by target: "+r)}}function X(r){let{multiple:e=!1,root:t=document.body,timeoutMs:i=0}=r;if(typeof e!="boolean"&&typeof e!="function")throw new TypeError(`'multiple' must be of type 'boolean' or 'function'. Received type: '${typeof e}'`);if(typeof e=="function"){let s=e();if(typeof s!="boolean")throw new TypeError(`'multiple' function must return a boolean. Received type: '${typeof s}'`)}if(!(t instanceof HTMLElement))throw new TypeError(`'root' must be of type 'HTMLElement'. Received type: '${typeof t}'`);if(typeof i!="number")throw new TypeError(`'timeout' must be of type 'number'. Received type: '${typeof i}'`)}function W(){return{get:(r,e)=>{if(e.toString().startsWith("_"))return;let t=r[e];return typeof t=="function"&&e!=="onceLoaded"?(...i)=>(r.onceLoaded(()=>t.apply(r,i)),r):t}}}async function J(r){try{let e=await H.getRecord("systemforms",r),{formxml:t}=e,s=new DOMParser().parseFromString(t,"application/xml"),n=z(s.getElementsByTagName("control")),o=z(s.getElementsByTagName("section")),l=z(s.getElementsByTagName("tab")),a=await Promise.all([...n,...o,...l]);return D(a.filter(c=>c!==null))}catch(e){throw e instanceof Error?(console.error(e.message),e):(console.error(e),new Error(String(e)))}}function z(r){return Array.from(r).map(e=>{let t=K(e.tagName),i=e.getAttribute(t);if(!i)return null;let s=Q(e.tagName,i);return s?O(s).catch(n=>(console.warn(`Failed to create a reference to the form field: ${i}`,n),null)):null}).filter(Boolean)}function K(r){return r==="control"?"id":r==="tab"||r==="section"?"name":"id"}function Q(r,e){return r==="control"?`#${e}`:r==="tab"||r==="section"?`[data-name="${e}"]`:null}var x=class extends HTMLElement{element;constructor(){if(!document)throw new Error("Cannot instantiate 'LoadingSpinner': No DOM Found");super(),this.id="loader",this.classList.add("loader-overlay","hidden"),this.element=document.createElement("div"),this.element.classList.add("spinner-border","text-light"),this.element.role="status",this.appendChild(this.element);let e=document.createElement("span");e.classList.add("visually-hidden"),e.textContent="Loading...",this.element.appendChild(e),document.body.appendChild(this)}hide(){this.classList.add("hidden")}show(){this.classList.remove("hidden")}},Y=`loading-${crypto.randomUUID()}`;customElements.define(Y,x);export{H as API,x as LoadingSpinner,J as bindForm,O as get,E as waitFor};
|
|
3
3
|
/*! For license information please see index.js.LEGAL.txt */
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
|
5
5
|
|
package/dist/src/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/safeAjax.ts", "../../src/core/API.ts", "../../src/ancillary/VisibilityManager.ts", "../../src/constants/EventTypes.ts", "../../src/constants/symbols.ts", "../../src/ancillary/InfoElement.ts", "../../src/core/waitFor.ts", "../../src/errors/errors.ts", "../../src/ancillary/DOMNodeReference.ts", "../../src/utils/InputMask.ts", "../../src/utils/PhoneNumberMask.ts", "../../src/ancillary/EventManager.ts", "../../src/ancillary/Radio.ts", "../../src/ancillary/ValueManager.ts", "../../src/utils/MoneyMask.ts", "../../src/core/PowerPagesElement.ts", "../../src/core/PowerPagesElementArray.ts", "../../src/utils/enhanceArray.ts", "../../src/core/getPowerPagesElement.ts", "../../src/core/bindForm.ts", "../../src/ancillary/LoadingSpinner.ts"],
|
|
4
|
-
"sourcesContent": ["// @ts-nocheck\r\n// Assume these globals are available in the PowerPages runtime:\r\ndeclare const shell: {\r\n getTokenDeferred(): JQuery.Promise<string>;\r\n};\r\n\r\ndeclare function validateLoginSession<T>(\r\n data: T,\r\n textStatus: string,\r\n jqXHR: JQuery.jqXHR,\r\n resolve: (value?: T | JQuery.Promise<T>) => void\r\n): void;\r\n\r\n/**\r\n * Custom HTTP wrapper function that handles authentication for the call from within PowerPages for you, making it all the easier to make API calls with {@link API}\r\n */\r\nexport default function safeAjax<T = any>(options: JQuery.AjaxSettings) {\r\n const deferredAjax = $.Deferred<T>();\r\n\r\n // shell is only available via runtime in a PowerPages portal\r\n\r\n shell\r\n .getTokenDeferred()\r\n .done(function (token) {\r\n // add headers for AJAX\r\n if (!options.headers) {\r\n $.extend(options, {\r\n headers: {\r\n __RequestVerificationToken: token,\r\n },\r\n });\r\n } else {\r\n options.headers[\"__RequestVerificationToken\"] = token;\r\n }\r\n $.ajax(options)\r\n .done(function (data: any, textStatus: string, jqXHR: any) {\r\n //eslint-disable-next-line\r\n validateLoginSession(data, textStatus, jqXHR, deferredAjax.resolve);\r\n })\r\n .fail(deferredAjax.reject); //AJAX\r\n })\r\n .fail(function () {\r\n deferredAjax.rejectWith(this, arguments); // on token failure pass the token AJAX and args\r\n });\r\n\r\n return deferredAjax.promise();\r\n}\r\n", "//@ts-nocheck\r\nimport safeAjax from \"../utils/safeAjax.ts\";\r\n\r\ninterface ODataJSON extends object {\r\n [key: `${string}@odata.bind` | string]: any;\r\n}\r\n\r\n/**\r\n * Provides abstract class `API` that allows basic create, read, and update operations in DataVerse via the PowerPages API\r\n * @method `createRecord` - Create a record in DataVerse\r\n * @method `getRecord<T>` - Get a record by ID from DataVerse\r\n * @method `getMultiple` - Get multiple records from DataVerse; with optional OData filtering\r\n * @method `updateRecord` - Update a record by ID in DataVerse\r\n */\r\nabstract class API {\r\n /**\r\n * @param tableSetName The dataverse set name for the table that you are updating a record in\r\n * @param data The JSON of the fields and data that are to be updated on the targeted record\r\n * @returns a Promise resolving the successful results *[record id]* of the POST request, or rejecting the failed results *[error]* of the POST request.\r\n */\r\n static createRecord(tableSetName: string, data: ODataJSON): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n safeAjax({\r\n type: \"POST\",\r\n url: `/_api/${tableSetName}`,\r\n data: JSON.stringify(data),\r\n contentType: \"application/json\",\r\n success: function (_response, _status, xhr) {\r\n resolve(xhr.getResponseHeader(\"entityid\"));\r\n },\r\n error: (error) => {\r\n reject(error);\r\n },\r\n });\r\n });\r\n }\r\n /**\r\n *\r\n * @param tableSetName The DataVerse SET name of the table being queried\r\n * @param recordID the GUID of the records to be retrieved\r\n * @param ODataQueryString *OPTIONAL* if desired, enter your own custom OData query for advanced GET results. e.g.: ?$select=column1,column2,column3\r\n * @returns a Promise resolving the successful results of the GET request, or rejecting the failed results of the GET request\r\n */\r\n static getRecord<T>(\r\n tableSetName: string,\r\n recordID: string,\r\n ODataQueryString?: string\r\n ): Promise<T> {\r\n return new Promise((resolve, reject) => {\r\n const url = `/_api/${tableSetName}(${recordID})${\r\n ODataQueryString ? `${ODataQueryString}` : \"\"\r\n }`;\r\n\r\n safeAjax({\r\n type: \"GET\",\r\n url: url,\r\n success: resolve,\r\n error: reject,\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * More flexible method for building completely custom queries\r\n */\r\n static request(\r\n query: string,\r\n options: JQuery.AjaxSettings\r\n ): Promise<Response | Error> {\r\n return new Promise((success, error) => {\r\n const url = `/_api/${query}`;\r\n safeAjax({\r\n url,\r\n ...options,\r\n });\r\n });\r\n }\r\n /**\r\n *\r\n * @param tableSetName The dataverse set name of the table being queried\r\n * @param queryParameters *OPTIONAL* the OData query parameters for refining search results: *format = $filter=filters&$select=columns*\r\n * @returns a Promise resolving the successful results of the GET request, or rejecting the failed results of the GET request\r\n */\r\n static getMultiple<T = object>(\r\n tableSetName: string,\r\n queryParameters?: string\r\n ): Promise<Array<T>> {\r\n return new Promise((resolve, reject) => {\r\n // Construct the URL based on the presence of query parameters\r\n const url = `/_api/${tableSetName}${\r\n queryParameters ? `?${queryParameters}` : \"\"\r\n }`;\r\n\r\n safeAjax({\r\n type: \"GET\",\r\n url: url,\r\n success: function (response) {\r\n resolve(response.value);\r\n },\r\n error: reject,\r\n });\r\n });\r\n }\r\n\r\n /**\r\n *\r\n * @param tableSetName The dataverse set name for the table that you are updating a record in\r\n * @param recordId The GUID of the record that is being updated\r\n * @param data The JSON of the fields and data that are to be updated on the targeted record\r\n * @returns A Promise with the results of the API execution\r\n */\r\n static updateRecord(\r\n tableSetName: string,\r\n recordId: string,\r\n data: ODataJSON\r\n ): Promise<any> {\r\n return new Promise((resolve, reject) => {\r\n const url = `/_api/${tableSetName}(${recordId})`;\r\n\r\n safeAjax({\r\n type: \"PATCH\",\r\n url: url,\r\n data: JSON.stringify(data),\r\n success: resolve,\r\n error: reject,\r\n });\r\n });\r\n }\r\n}\r\n\r\nexport default API;\r\n", "export default class VisibilityManager {\r\n private declare visibilityController: HTMLElement | null;\r\n private defaultVisibility: string | null;\r\n\r\n public set defaultDisplay(newValue: string | null) {\r\n this.defaultVisibility = newValue;\r\n }\r\n\r\n constructor(target: HTMLElement) {\r\n // Set the default visibility controller to the element itself\r\n this.visibilityController = target;\r\n\r\n // If the element is a table, use its closest fieldset as the controller\r\n if (target.tagName === \"TABLE\") {\r\n const fieldset = target.closest(\"fieldset\");\r\n if (fieldset) {\r\n this.visibilityController = fieldset;\r\n }\r\n }\r\n\r\n // For specific tag types, use the closest 'td' if available as the controller\r\n const tagsRequiringTdParent = [\r\n \"SPAN\",\r\n \"INPUT\",\r\n \"TEXTAREA\",\r\n \"SELECT\",\r\n \"TABLE\",\r\n ];\r\n if (tagsRequiringTdParent.includes(target.tagName)) {\r\n const tdParent = target.closest(\"td\");\r\n if (tdParent) {\r\n this.visibilityController = tdParent;\r\n }\r\n }\r\n\r\n this.defaultVisibility = this.visibilityController.style.display;\r\n }\r\n\r\n public hide(): void {\r\n this.visibilityController!.style.display = \"none\";\r\n }\r\n\r\n public show(): void {\r\n this.visibilityController!.style.display = this.defaultVisibility!;\r\n }\r\n\r\n public toggleVisibility(shouldShow: boolean): void {\r\n shouldShow ? this.show() : this.hide();\r\n }\r\n\r\n public getVisibility(): true | false {\r\n return (\r\n window.getComputedStyle(this.visibilityController!).display !== \"none\" &&\r\n window.getComputedStyle(this.visibilityController!).visibility !==\r\n \"hidden\" &&\r\n this.visibilityController!.getBoundingClientRect().height > 0 &&\r\n this.visibilityController!.getBoundingClientRect().width > 0\r\n );\r\n }\r\n\r\n public destroy(): void {\r\n this.visibilityController = null;\r\n this.defaultVisibility = null;\r\n }\r\n}\r\n", "/**\r\n * For use in setting up event management in the instances of PowerPagesElement\r\n * @see {@link PowerPagesElement}\r\n */\r\nexport const EventTypes = {\r\n CHECKBOX: \"click\",\r\n RADIO: \"click\",\r\n SELECT: \"change\",\r\n TEXT: \"keyup\",\r\n DEFAULT: \"input\",\r\n} as const;\r\n", "export const init: symbol = Symbol(\"init\");\r\nexport const destroy: symbol = Symbol(\"destroy\");\r\n", "/**\r\n *\r\n * @param {string} titleString The text to display in the tooltip flyout content\r\n * @param iconStyle Optional CSS styles to apply to the info icon\r\n * @returns\r\n */\r\n/********/ /********/ export default class InfoElement extends HTMLElement {\r\n private flyoutContent: HTMLDivElement;\r\n private icon: HTMLElement;\r\n private observers: MutationObserver[] = [];\r\n\r\n /********/ constructor(\r\n titleString: string,\r\n iconStyle?: Partial<CSSStyleDeclaration>\r\n ) {\r\n super();\r\n // Input validation remains the same\r\n if (typeof titleString !== \"string\") {\r\n throw new Error(\r\n `argument \"titleString\" must be of type \"string\". Received: \"${typeof titleString}\"`\r\n );\r\n }\r\n if (iconStyle && typeof iconStyle !== \"object\") {\r\n throw new Error(\r\n `argument \"iconStyle\" must be of type \"object\". Received: \"${typeof iconStyle}\"`\r\n );\r\n }\r\n\r\n this.classList.add(\"info-icon\");\r\n\r\n this.icon = document.createElement(\"i\");\r\n this.icon.classList.add(\"fa\", \"fa-solid\", \"fa-info-circle\");\r\n this.icon.setAttribute(\"aria-label\", \"Info\");\r\n this.icon.style.cursor = \"pointer\";\r\n\r\n this.flyoutContent = document.createElement(\"div\");\r\n this.flyoutContent.innerHTML = titleString;\r\n this.flyoutContent.classList.add(\"flyout-content\");\r\n\r\n this.appendChild(this.icon);\r\n this.appendChild(this.flyoutContent);\r\n\r\n if (iconStyle) {\r\n Object.assign(this.icon.style, iconStyle);\r\n }\r\n\r\n this.handleClick = this.handleClick.bind(this);\r\n this.handleResize = this.handleResize.bind(this);\r\n this.handleTouchStart = this.handleTouchStart.bind(this);\r\n this.handleMouseEnter = this.handleMouseEnter.bind(this);\r\n this.handleMouseLeave = this.handleMouseLeave.bind(this);\r\n this.handleScroll = this.handleScroll.bind(this);\r\n\r\n this.flyoutContent.style.minWidth = this.getDesiredWidth();\r\n\r\n this.flyoutContent.style.display = \"none\";\r\n\r\n this.attachEventListeners();\r\n this.setupObservers();\r\n }\r\n\r\n /********/ private attachEventListeners(): void {\r\n document.body.addEventListener(\"click\", this.handleClick);\r\n self.addEventListener(\"resize\", this.handleResize);\r\n this.icon.addEventListener(\"touchstart\", this.handleTouchStart);\r\n this.addEventListener(\"mouseenter\", this.handleMouseEnter);\r\n this.addEventListener(\"mouseleave\", this.handleMouseLeave);\r\n self.addEventListener(\"scroll\", this.handleScroll);\r\n }\r\n\r\n /********/ private setupObservers(): void {\r\n // observe if element is removed, so that we can perform cleanup\r\n const _destroy_observer = new MutationObserver((mutations) => {\r\n for (const mut of mutations) {\r\n for (const node of Array.from(mut.removedNodes)) {\r\n if (node === this) {\r\n this.destroy();\r\n return;\r\n }\r\n }\r\n }\r\n });\r\n _destroy_observer.observe(document, {\r\n childList: true,\r\n subtree: true,\r\n attributes: false,\r\n });\r\n\r\n // observe for changes in the DOM, and trigger position\r\n const _position_observer = new MutationObserver(\r\n () => this.updateFlyoutWidth\r\n );\r\n _position_observer.observe(document, {\r\n childList: true,\r\n subtree: true,\r\n attributes: false,\r\n });\r\n\r\n // track observers for cleanup\r\n this.observers.push(_destroy_observer, _position_observer);\r\n }\r\n\r\n /********/ private getDesiredWidth(): string {\r\n // Get a reasonable width that works for center positioning\r\n const viewportWidth = self.innerWidth;\r\n const maxWidth = Math.min(viewportWidth - 40, 600); // Max 600px wide with 20px padding on each side\r\n return `${maxWidth}px`;\r\n }\r\n\r\n /********/ private positionFlyout(): void {\r\n // Always position the flyout in the center of the screen\r\n this.flyoutContent.style.display = \"block\";\r\n // Get the icon's position relative to the viewport\r\n const iconRect = this.icon.getBoundingClientRect();\r\n const flyoutRect = this.flyoutContent.getBoundingClientRect();\r\n const viewportHeight = self.innerHeight;\r\n const margin = 5; // Space between icon and flyout\r\n let topPosition = iconRect.bottom - margin; // Default below the icon\r\n // If the flyout would go beyond the viewport, position it above\r\n if (topPosition + flyoutRect.height > viewportHeight) {\r\n topPosition = iconRect.top - flyoutRect.height; // Move above the icon\r\n }\r\n // Apply positions\r\n this.flyoutContent.style.top = `${topPosition}px`;\r\n\r\n // then, adjust centeredness based on layout of page\r\n }\r\n\r\n /********/ private updateFlyoutWidth(): void {\r\n this.flyoutContent.style.minWidth = this.getDesiredWidth();\r\n }\r\n\r\n /********/ private handleClick(e: Event): void {\r\n if (!this.contains(e.target as Node)) {\r\n this.flyoutContent.style.display = \"none\";\r\n }\r\n }\r\n\r\n /********/ private handleResize(_e: Event): void {\r\n this.flyoutContent.style.minWidth = this.getDesiredWidth();\r\n }\r\n\r\n /********/ private handleTouchStart(): void {\r\n this.flyoutContent.style.display =\r\n this.flyoutContent.style.display === \"block\" ? \"none\" : \"block\";\r\n if (this.flyoutContent.style.display === \"block\") {\r\n this.positionFlyout();\r\n }\r\n }\r\n\r\n /********/ private handleMouseEnter(_e: MouseEvent): void {\r\n this.positionFlyout();\r\n }\r\n\r\n /********/ private handleMouseLeave(event: MouseEvent): void {\r\n // Check if we're not moving to a child element\r\n const relatedTarget = event.relatedTarget as Node;\r\n if (!this.contains(relatedTarget)) {\r\n this.flyoutContent.style.display = \"none\";\r\n }\r\n }\r\n\r\n /********/ private handleScroll(): void {\r\n const previousFlyoutDisplay = this.flyoutContent.style.display;\r\n if (previousFlyoutDisplay === \"none\") return;\r\n\r\n this.positionFlyout();\r\n\r\n this.flyoutContent.style.display = previousFlyoutDisplay;\r\n }\r\n\r\n /********/ private destroy(): void {\r\n document.body.removeEventListener(\"click\", this.handleClick);\r\n self.removeEventListener(\"resize\", this.handleResize);\r\n this.icon.removeEventListener(\"touchstart\", this.handleTouchStart);\r\n this.removeEventListener(\"mouseenter\", this.handleMouseEnter);\r\n this.removeEventListener(\"mouseleave\", this.handleMouseLeave);\r\n self.removeEventListener(\"scroll\", this.handleScroll);\r\n\r\n this.observers.forEach((obv) => obv.disconnect());\r\n }\r\n}\r\nconst uid: string = `info-icon-${crypto.randomUUID()}`;\r\ncustomElements.define(uid, InfoElement);\r\n", "/**\r\n * Provides an async way to capture DOM elements; for when querySelector cannot capture the target due to async DOM content loading\r\n * @param **target** - basic querySelector syntax to select an element\r\n * @param **root** - optional parameter to replace document as the root from which to perform the node search\r\n * @returns the element(s) targeted by the `querySelector` string\r\n */\r\nexport default function waitFor(\r\n target: string,\r\n root: Element | Document,\r\n multiple: false,\r\n debounceTime: number\r\n): Promise<HTMLElement>;\r\n\r\nexport default function waitFor(\r\n target: string,\r\n root: Element | Document,\r\n multiple: true,\r\n debounceTime: number\r\n): Promise<HTMLElement[]>;\r\n\r\nexport default function waitFor(\r\n target: string,\r\n root: Element | Document = document,\r\n multiple: boolean = false,\r\n debounceTime: number\r\n): Promise<HTMLElement | HTMLElement[]> {\r\n //\r\n return new Promise((resolve, reject) => {\r\n //\r\n if (multiple) {\r\n //\r\n let timeout: any;\r\n const observedElements: HTMLElement[] = [];\r\n const observedSet: Set<HTMLElement> = new Set();\r\n\r\n if (debounceTime < 1) {\r\n return resolve(\r\n <HTMLElement[]>Array.from(root.querySelectorAll(<string>target))\r\n );\r\n }\r\n const observer = new MutationObserver(() => {\r\n const found = <HTMLElement[]>(\r\n Array.from(root.querySelectorAll(<string>target))\r\n );\r\n\r\n // If elements are found, store them in observedElements\r\n found.forEach((element) => {\r\n if (!observedSet.has(element)) {\r\n observedSet.add(element);\r\n observedElements.push(element);\r\n }\r\n });\r\n\r\n // Clear the previous timeout and set a new one\r\n clearTimeout(timeout);\r\n timeout = setTimeout(() => {\r\n // Resolve the promise after debounce period if no more mutations\r\n if (observedElements.length > 0) {\r\n observer.disconnect();\r\n resolve(observedElements);\r\n } else {\r\n reject(\r\n new Error(\r\n `No elements found with target: \"${target}\" within ${\r\n debounceTime / 1000\r\n } seconds. If the element you are expecting has not loaded yet, consider raising your timeout.`\r\n )\r\n );\r\n }\r\n }, debounceTime);\r\n });\r\n\r\n observer.observe(root, {\r\n childList: true,\r\n subtree: true,\r\n attributes: false,\r\n });\r\n //\r\n } else {\r\n // Create observer to watch for target in DOM\r\n const observer = new MutationObserver(() => {\r\n const observedElement = <HTMLElement>root.querySelector(<string>target);\r\n if (observedElement) {\r\n clearTimeout(timeout);\r\n observer.disconnect();\r\n resolve(observedElement);\r\n }\r\n });\r\n const timeout = setTimeout(() => {\r\n observer.disconnect();\r\n reject(\r\n new Error(\r\n `Element not found by target: \"${target}\" within ${\r\n debounceTime / 1000\r\n } second. If the element you are expecting has not loaded yet, consider raising your timeout.`\r\n )\r\n );\r\n }, debounceTime);\r\n\r\n const element = <HTMLElement>root.querySelector(<string>target);\r\n if (element) {\r\n clearTimeout(timeout);\r\n return resolve(element);\r\n }\r\n\r\n observer.observe(root, {\r\n subtree: true,\r\n attributes: true,\r\n childList: true, // Detects added/removed child elements\r\n });\r\n //\r\n }\r\n //\r\n });\r\n //\r\n}\r\n", "import type DOMNodeReference from \"../ancillary/DOMNodeReference.ts\";\r\n\r\nclass CustomError extends Error {\r\n public node: DOMNodeReference;\r\n constructor(node: DOMNodeReference, message: string) {\r\n super(message);\r\n\r\n this.node = node;\r\n\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, this.constructor);\r\n }\r\n }\r\n}\r\n\r\nclass InitializationError extends CustomError {\r\n constructor(node: DOMNodeReference, error: string) {\r\n super(\r\n node,\r\n `There was an error initializing a DOMNodeReference for target: ${node.target}, :: ${error}`\r\n );\r\n }\r\n}\r\n\r\nclass NodeNotFoundError extends CustomError {\r\n constructor(node: DOMNodeReference) {\r\n super(node, `The targeted DOM element was not found: ${node.target}`);\r\n }\r\n}\r\n\r\nclass Page_ValidatorsNotFoundError extends CustomError {\r\n constructor(node: DOMNodeReference) {\r\n super(node, \"Page_Validators could not be found\");\r\n }\r\n}\r\n\r\nclass BusinessRuleError extends CustomError {\r\n constructor(node: DOMNodeReference) {\r\n super(node, `Error applying business rule to target: ${node.target}`);\r\n }\r\n}\r\n\r\nclass SelfReferenceError extends CustomError {\r\n constructor(node: DOMNodeReference) {\r\n super(\r\n node,\r\n \"Self-referential dependency found. A DOMNodeReference cannot depend on itself\"\r\n );\r\n }\r\n}\r\n\r\nclass LabelNotFoundError extends CustomError {\r\n constructor(node: DOMNodeReference) {\r\n super(node, `No label could be found for the target: ${node.target}`);\r\n }\r\n}\r\n\r\nclass IncorrectParameterError extends CustomError {\r\n constructor(\r\n node: DOMNodeReference,\r\n functionName: string,\r\n argName: string,\r\n expectedTypes: string[],\r\n receivedType: any\r\n ) {\r\n const concatTypes = expectedTypes.join(\" or \");\r\n\r\n super(\r\n node,\r\n `${functionName} expects ${argName} to be of type ${concatTypes}. Received: ${\r\n receivedType === null ? \"null\" : typeof receivedType\r\n }`\r\n );\r\n }\r\n}\r\n\r\nconst Errors = {\r\n NodeNotFoundError,\r\n InitializationError,\r\n Page_ValidatorsNotFoundError,\r\n BusinessRuleError,\r\n SelfReferenceError,\r\n LabelNotFoundError,\r\n IncorrectParameterError,\r\n};\r\n\r\nexport default Errors;\r\n", "import type EventManager from \"../ancillary/EventManager.ts\";\r\nimport type ValueManager from \"../ancillary/ValueManager.ts\";\r\nimport type VisibilityManager from \"./VisibilityManager.ts\";\r\nimport { EventTypes } from \"../constants/EventTypes.ts\";\r\nimport { init, destroy } from \"../constants/symbols.ts\";\r\nimport InfoElement from \"./InfoElement.ts\";\r\nimport waitFor from \"../core/waitFor.ts\";\r\nimport Errors from \"../errors/errors.ts\";\r\nimport DOMPurify from \"DOMPurify\";\r\n\r\nexport default abstract class DOMNodeReference {\r\n // declare static properties\r\n static instances: DOMNodeReference[] = [];\r\n\r\n // allow for indexing methods with symbols\r\n [key: symbol]: (...arg: any[]) => any;\r\n\r\n // properties initialized in the constructor\r\n public target: Element | string;\r\n public logicalName?: string;\r\n public root: Element;\r\n protected timeoutMs: number;\r\n protected isLoaded: boolean;\r\n\r\n /**\r\n * The value of the element that this node represents\r\n * stays in syncs with the live DOM elements?.,m via event handler\r\n */\r\n public get value() {\r\n return this.valueManager!.value;\r\n }\r\n\r\n public set value(newValue) {\r\n this.valueManager!.setValue(newValue);\r\n }\r\n\r\n public get checked() {\r\n return this.valueManager!.checked;\r\n }\r\n\r\n public set defaultDisplay(newValue: string | null) {\r\n this.visibilityManager!.defaultDisplay = newValue;\r\n }\r\n\r\n /**\r\n * The element targeted when instantiating DOMNodeReference.\r\n * Made available in order to perform normal DOM traversal,\r\n * or access properties not available through this class.\r\n */\r\n public declare element: HTMLElement;\r\n public visibilityManager!: VisibilityManager | null;\r\n public valueManager!: ValueManager | null;\r\n public eventManager!: EventManager | null;\r\n\r\n /**\r\n * Creates an instance of DOMNodeReference.\r\n * @param target - The CSS selector to find the desired DOM element.\r\n * @param root - Optionally specify the element within to search for the element targeted by 'target'\r\n * Defaults to 'document.body'\r\n */\r\n /******/ /******/ constructor(\r\n target: Element | string,\r\n root: Element = document.body,\r\n timeoutMs: number\r\n ) {\r\n this.target = target;\r\n this.logicalName = this._extractLogicalName(target);\r\n this.root = root;\r\n this.timeoutMs = timeoutMs;\r\n this.isLoaded = false;\r\n\r\n // The rest of initialization.\r\n }\r\n\r\n protected async [init](): Promise<void> {\r\n if (this.target instanceof HTMLElement) {\r\n this.element = this.target;\r\n } else {\r\n this.element = (await waitFor(\r\n this.target as string,\r\n this.root,\r\n false,\r\n this.timeoutMs\r\n )) as HTMLElement;\r\n }\r\n\r\n if (!this.element) {\r\n throw new Errors.NodeNotFoundError(this);\r\n }\r\n }\r\n\r\n // force extensions of this class to implement these methods\r\n protected abstract initValueManager(): void;\r\n protected abstract initVisibilityManager(): void;\r\n protected abstract initEventManager(): void;\r\n\r\n protected _extractLogicalName(target: Element | string): string {\r\n if (typeof target !== \"string\") return \"\";\r\n\r\n const bracketMatch = target.match(/\\[([^\\]]+)\\]/);\r\n if (!bracketMatch) return target.replace(/[#\\[\\]]/g, \"\");\r\n\r\n const content = bracketMatch[1];\r\n const quoteMatch = content.match(/[\"']([^\"']+)[\"']/);\r\n return (quoteMatch?.[1] || content).replace(/[#\\[\\]]/g, \"\");\r\n }\r\n\r\n protected _valueSync(): void {\r\n if (!this._isValidFormElement(this.element)) return;\r\n\r\n this.updateValue();\r\n const eventType = this._determineEventType();\r\n this.eventManager!.registerDOMEventListener(\r\n this.element,\r\n eventType,\r\n this.updateValue.bind(this)\r\n );\r\n\r\n if (this._isDateInput()) {\r\n this._dateSync(this.element as HTMLInputElement);\r\n }\r\n }\r\n\r\n protected _determineEventType(): keyof GlobalEventHandlersEventMap {\r\n if (this.element instanceof HTMLSelectElement) return \"change\";\r\n if (this.element instanceof HTMLTextAreaElement) return \"keyup\";\r\n if (!(this.element instanceof HTMLInputElement)) return EventTypes.DEFAULT;\r\n\r\n return (\r\n EventTypes[this.element.type.toUpperCase() as keyof typeof EventTypes] ||\r\n EventTypes.DEFAULT\r\n );\r\n }\r\n\r\n protected _isDateInput(): boolean {\r\n return (\r\n this.element instanceof HTMLInputElement &&\r\n this.element.dataset.type === \"date\"\r\n );\r\n }\r\n\r\n protected _isValidFormElement(element: Element): element is FormElement {\r\n return (\r\n element instanceof HTMLInputElement ||\r\n element instanceof HTMLSelectElement ||\r\n element instanceof HTMLTextAreaElement ||\r\n element instanceof HTMLSpanElement ||\r\n element instanceof HTMLButtonElement ||\r\n element instanceof HTMLFieldSetElement\r\n );\r\n }\r\n\r\n protected async _dateSync(element: HTMLInputElement): Promise<void> {\r\n const parentElement = element.parentElement;\r\n if (!parentElement) {\r\n throw new DOMException(\"Date input must have a parent element\");\r\n }\r\n\r\n const dateNode = (await waitFor(\r\n \"[data-date-format]\",\r\n parentElement,\r\n false,\r\n 1500\r\n )) as HTMLElement;\r\n\r\n this.valueManager!.element = dateNode;\r\n\r\n this.eventManager!.registerDOMEventListener(\r\n dateNode,\r\n \"select\",\r\n this.updateValue.bind(this)\r\n );\r\n }\r\n\r\n protected _bindMethods() {\r\n const prototype = Object.getPrototypeOf(this);\r\n\r\n for (const key of Object.getOwnPropertyNames(prototype) as Array<\r\n keyof this\r\n >) {\r\n const value = this[key];\r\n\r\n // Ensure we're binding only functions and skip the constructor\r\n if (key !== \"constructor\" && typeof value === \"function\") {\r\n this[key] = value.bind(this);\r\n }\r\n }\r\n }\r\n\r\n protected [destroy](): void {\r\n // Clear other references\r\n this.isLoaded = false;\r\n this.value = null;\r\n\r\n this.eventManager!.destroy();\r\n this.eventManager = null;\r\n this.visibilityManager!.destroy();\r\n this.visibilityManager = null;\r\n this.valueManager!.destroy();\r\n this.valueManager = null;\r\n }\r\n\r\n /**\r\n * Updates the value and checked state based on element type\r\n * @public\r\n */\r\n public async updateValue(e?: Event): Promise<void> {\r\n if (e && !e.isTrusted) return;\r\n await this.valueManager!.updateValue(e);\r\n this.triggerDependentsHandlers();\r\n }\r\n\r\n protected triggerDependentsHandlers(): void {\r\n this.eventManager!.dispatchDependencyHandlers();\r\n }\r\n\r\n /**\r\n * Sets up an event listener based on the specified event type, executing the specified\r\n * event handler\r\n * @param eventType - The DOM event to watch for\r\n * @param eventHandler - The callback function that runs when the\r\n * specified event occurs.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public on<K extends keyof GlobalEventHandlersEventMap>(\r\n eventType: K,\r\n eventHandler: (\r\n this: DOMNodeReference,\r\n e: GlobalEventHandlersEventMap[K]\r\n ) => void\r\n ): DOMNodeReference {\r\n if (typeof eventHandler !== \"function\") {\r\n throw new Errors.IncorrectParameterError(\r\n this,\r\n \"on\",\r\n \"eventHandler\",\r\n [\"function\"],\r\n typeof eventHandler\r\n );\r\n }\r\n\r\n const handler = eventHandler as (this: DOMNodeReference, e: Event) => void;\r\n this.eventManager!.registerDOMEventListener(\r\n this.element,\r\n eventType,\r\n handler.bind(this)\r\n );\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Hides the element by setting its display style to \"none\".\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public hide(): DOMNodeReference {\r\n this.visibilityManager!.hide();\r\n return this;\r\n }\r\n\r\n /**\r\n * Shows the element by restoring its default display style.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public show(): DOMNodeReference {\r\n this.visibilityManager!.show();\r\n return this;\r\n }\r\n\r\n /**\r\n * @param shouldShow - Either a function that returns true or false,\r\n * or a natural boolean to determine the visibility of this\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public toggleVisibility(\r\n shouldShow: EvaluationFunction | boolean\r\n ): DOMNodeReference {\r\n const bool: boolean =\r\n shouldShow instanceof Function ? shouldShow.call(this) : shouldShow;\r\n\r\n this.visibilityManager!.toggleVisibility(bool);\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the value of the HTML element.\r\n * @param value - The value to set for the HTML element.\r\n * for parents of boolean radios, pass true or false as value, or\r\n * an expression returning a boolean\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public setValue(value: (() => any) | any): DOMNodeReference {\r\n if (value instanceof Function) {\r\n value = value();\r\n }\r\n this.valueManager!.setValue(value);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Disables the element so that users cannot input any data\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public disable(): DOMNodeReference {\r\n (this.element as HTMLInputElement).disabled = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Clears all values and states of the element.\r\n * Handles different input types appropriately, and can be called\r\n * on an element containing N child inputs to clear all\r\n */\r\n public clearValue(): void {\r\n this.valueManager!.clearValue();\r\n\r\n // Handle nested input elements in container elements\r\n if (this._getChildren()) {\r\n this.callAgainstChildrenInputs((child) => child.clearValue());\r\n }\r\n }\r\n\r\n protected _getChildren(): DOMNodeReference[] | null {\r\n const childInputs: Element[] = Array.from(\r\n this.element.querySelectorAll(\"input, select, textarea\")\r\n );\r\n const childIds: string[] = childInputs.map((input) => {\r\n return input.id;\r\n });\r\n\r\n const children = DOMNodeReference.instances.filter((ref) => {\r\n return childIds.includes(ref.element.id);\r\n });\r\n\r\n return children.length > 0 ? children : null;\r\n }\r\n\r\n protected callAgainstChildrenInputs(\r\n callback: (child: DOMNodeReference) => any\r\n ): void {\r\n // Handle nested input elements in container elements\r\n const children: DOMNodeReference[] | null = this._getChildren();\r\n if (!children) {\r\n console.error(\"No child inputs found for target: \", this);\r\n return;\r\n }\r\n\r\n for (const child of children) {\r\n callback(child);\r\n }\r\n }\r\n\r\n /**\r\n * Enables the element so that users can input data\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public enable(): DOMNodeReference {\r\n (this.element as HTMLInputElement).disabled = false;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param elements - The elements to prepend to the element targeted by this.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public prepend(...elements: HTMLElement[]): DOMNodeReference {\r\n this.element.prepend(...elements);\r\n return this;\r\n }\r\n\r\n /**\r\n * Appends child elements to the HTML element.\r\n * @param elements - The elements to append to the element targeted by this.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public append(...elements: HTMLElement[]): DOMNodeReference {\r\n this.element.append(...elements);\r\n return this;\r\n }\r\n\r\n /**\r\n * Inserts elements before the HTML element.\r\n * @param elements - The elements to insert before the HTML element.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public before(...elements: HTMLElement[]): DOMNodeReference {\r\n this.element.before(...elements);\r\n return this;\r\n }\r\n\r\n /**\r\n * Inserts elements after the HTML element.\r\n * @param elements - The elements to insert after the HTML element.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public after(...elements: HTMLElement[]): DOMNodeReference {\r\n this.element.after(...elements);\r\n return this;\r\n }\r\n\r\n /**\r\n * Retrieves the label associated with the HTML element.\r\n * @returns The label element associated with this element.\r\n */\r\n public getLabel(): HTMLElement | null {\r\n const label =\r\n (document.querySelector(`#${this.element.id}_label`) as HTMLElement) ||\r\n null;\r\n if (!label) throw new Errors.LabelNotFoundError(this);\r\n return label;\r\n }\r\n\r\n /**\r\n * Adds a tooltip with specified text to the label associated with the HTML element.\r\n * @param innerHTML - The innerHTML to append into the tooltip.\r\n * @param containerStyle - Optional object with CSS Styles to apply to the info element\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public addLabelTooltip(\r\n innerHTML: string,\r\n containerStyle?: Partial<CSSStyleDeclaration>\r\n ): DOMNodeReference {\r\n const safeHTML = DOMPurify.sanitize(innerHTML);\r\n this.getLabel()?.append(\r\n new InfoElement(safeHTML, containerStyle || undefined)\r\n );\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds a tooltip with the specified text to the element\r\n * @param innerHTML - The innerHTML to append into the tooltip\r\n * @param containerStyle - Optional object with CSS Styles to apply to the info element\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public addTooltip(\r\n innerHTML: string,\r\n containerStyle?: Partial<CSSStyleDeclaration>\r\n ): DOMNodeReference {\r\n const safeHTML = DOMPurify.sanitize(innerHTML);\r\n this.append(new InfoElement(safeHTML, containerStyle || undefined));\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the inner HTML content of the HTML element.\r\n * @param string - The text to set as the inner HTML of the element.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n set innerHTML(innerHTML: string) {\r\n const safeHTML = DOMPurify.sanitize(innerHTML);\r\n this.element.innerHTML = safeHTML;\r\n }\r\n\r\n /**\r\n * Removes this element from the DOM\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public remove() {\r\n this.element.remove();\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets inline CSS styles on the element.\r\n * @param options - An object containing CSS property-value pairs, e.g., { display: 'block' }.\r\n * @returns The instance, enabling method chaining.\r\n */\r\n public setStyle(options: Partial<CSSStyleDeclaration>): DOMNodeReference {\r\n if (options === null || typeof options !== \"object\") {\r\n throw new Errors.IncorrectParameterError(\r\n this,\r\n \"setStyle\",\r\n \"options\",\r\n [\"Partial<CSSStyleDeclaration>\"],\r\n typeof options\r\n );\r\n }\r\n\r\n // Iterate over own enumerable properties of the options object.\r\n Object.entries(options).forEach(([prop, value]) => {\r\n // Skip properties that are undefined.\r\n if (value !== undefined) {\r\n // Here we cast 'prop' as a key of CSSStyleDeclaration.\r\n // Using bracket notation allows dynamic property access.\r\n (this.element.style as any)[prop] = value;\r\n }\r\n });\r\n\r\n return this;\r\n }\r\n\r\n // #region Apply Business Rule\r\n /**\r\n * Applies a business rule to manage visibility, required state, value, and disabled state dynamically.\r\n * @see {@link BusinessRule}\r\n * @param rule The business rule containing conditions for various actions.\r\n * @param dependencies For re-evaluation of conditions when the state of the dependencies change\r\n * @returns Instance of this for method chaining.\r\n */\r\n public applyBusinessRule(\r\n rule: BusinessRule,\r\n dependencies: DependencyArray<DOMNodeReference>\r\n ): DOMNodeReference {\r\n try {\r\n // Create validator if needed (this is only needed once during setup)\r\n if (rule.setRequirements) {\r\n this._setupRequirementsValidator(rule.setRequirements());\r\n }\r\n\r\n // Apply the rules immediately\r\n const handler = this._createBusinessRuleHandler(rule);\r\n handler();\r\n\r\n // Setup dependency tracking\r\n if (dependencies.length) {\r\n this._configureDependencyTracking(handler, dependencies);\r\n }\r\n\r\n return this;\r\n } catch (error) {\r\n if (error instanceof Error) throw error;\r\n else throw new Errors.BusinessRuleError(this);\r\n }\r\n }\r\n // #region =========\r\n\r\n private _setupRequirementsValidator(\r\n requirements: FieldValidationRules\r\n ): void {\r\n const { isRequired, isValid } = requirements;\r\n\r\n if (typeof Page_Validators === \"undefined\") {\r\n throw new Errors.Page_ValidatorsNotFoundError(this);\r\n }\r\n\r\n let evaluationFunction = () => true;\r\n\r\n if (isRequired && isValid) {\r\n evaluationFunction = () => {\r\n const isFieldRequired = isRequired.call(this);\r\n const isFieldVisible = this.visibilityManager!.getVisibility();\r\n return (\r\n !isFieldRequired ||\r\n (isFieldVisible && isValid.call(this, isFieldRequired))\r\n );\r\n };\r\n } else if (isValid) {\r\n evaluationFunction = () => {\r\n const isFieldVisible = this.visibilityManager!.getVisibility();\r\n return isFieldVisible && isValid.call(this, false);\r\n };\r\n } else if (isRequired) {\r\n evaluationFunction = () => {\r\n const isFieldVisible = this.visibilityManager!.getVisibility();\r\n return isFieldVisible && isRequired.call(this);\r\n };\r\n }\r\n\r\n this._createValidator(evaluationFunction);\r\n }\r\n\r\n private _createBusinessRuleHandler(rule: BusinessRule): BusinessRuleHandler {\r\n return (): void => {\r\n let clearValues: boolean = false;\r\n\r\n // Handle visibility\r\n if (rule.setVisibility) {\r\n const visibilityCondition = rule.setVisibility;\r\n const isVisible = visibilityCondition.call(this);\r\n clearValues = !isVisible;\r\n this.toggleVisibility(isVisible);\r\n }\r\n\r\n // Handle requirements\r\n if (rule.setRequirements && rule.setRequirements().isRequired) {\r\n const { isRequired } = rule.setRequirements();\r\n this.setRequiredLevel(isRequired!.call(this));\r\n }\r\n\r\n // Handle value setting\r\n if (rule.setValue) {\r\n const { condition, value } = rule.setValue();\r\n if (condition.call(this)) {\r\n const finalValue = value instanceof Function ? value() : value;\r\n this.setValue.call(this, finalValue);\r\n }\r\n }\r\n\r\n // Handle disabled state\r\n if (rule.setDisabled) {\r\n const disabledCondition = rule.setDisabled;\r\n disabledCondition.call(this) ? this.disable() : this.enable();\r\n }\r\n\r\n // Clear values if needed\r\n if (clearValues && !rule.setValue) {\r\n this.clearValue();\r\n }\r\n\r\n this.triggerDependentsHandlers();\r\n };\r\n }\r\n\r\n private _createValidator(evaluationFunction: EvaluationFunction): void {\r\n const fieldDisplayName = (() => {\r\n let label: any = this.getLabel();\r\n if (!label) {\r\n throw new Errors.LabelNotFoundError(this);\r\n }\r\n label = label.innerHTML;\r\n if (label.length > 50) {\r\n label = label.substring(0, 50) + \"...\";\r\n }\r\n return label;\r\n })();\r\n\r\n const validatorId = `${this.element.id}Validator`;\r\n\r\n const newValidator = document.createElement(\"span\");\r\n newValidator.style.display = \"none\";\r\n newValidator.id = validatorId;\r\n\r\n Object.assign(newValidator, {\r\n controltovalidate: this.element.id,\r\n errormessage: `<a href='#${this.element.id}_label'>${fieldDisplayName} is a required field</a>`,\r\n evaluationfunction: evaluationFunction.bind(this),\r\n });\r\n\r\n if (Page_Validators == undefined)\r\n throw new Errors.Page_ValidatorsNotFoundError(this);\r\n\r\n Page_Validators.push(newValidator);\r\n }\r\n\r\n private _configureDependencyTracking(\r\n handler: DependencyHandler,\r\n dependencies: DOMNodeReference[]\r\n ): void {\r\n if (dependencies.length < 1) {\r\n console.error(\r\n `powerpagestoolkit: No dependencies specified for ${this.element.id}. ` +\r\n \"Include all required nodes in the dependency array for proper tracking.\"\r\n );\r\n return;\r\n }\r\n\r\n dependencies.forEach((dependency) => {\r\n if (!dependency || !(dependency instanceof DOMNodeReference)) {\r\n throw new TypeError(\r\n \"Each dependency must be a valid DOMNodeReference instance\"\r\n );\r\n }\r\n\r\n // Check for self-referential dependency\r\n if (dependency.logicalName === this.logicalName) {\r\n throw new Errors.SelfReferenceError(this);\r\n }\r\n\r\n // The node that THIS depends on needs to be able to send notifications to its dependents\r\n // dependency.dependents.set(this, handler.bind(this));\r\n dependency.eventManager!.registerDependent(this, handler.bind(this));\r\n });\r\n }\r\n\r\n /**\r\n * Sets the required level for the field by adding or removing the \"required-field\" class on the label.\r\n *\r\n * @param isRequired Determines whether the field should be marked as required.\r\n * If true, the \"required-field\" class is added to the label; if false, it is removed.\r\n * @returns Instance of this [provides option to method chain]\r\n */\r\n public setRequiredLevel(\r\n isRequired: EvaluationFunction | boolean\r\n ): DOMNodeReference {\r\n if (isRequired instanceof Function) {\r\n isRequired.call(this)\r\n ? this.getLabel()?.classList.add(\"required-field\")\r\n : this.getLabel()?.classList.remove(\"required-field\");\r\n return this;\r\n } else {\r\n isRequired\r\n ? this.getLabel()?.classList.add(\"required-field\")\r\n : this.getLabel()?.classList.remove(\"required-field\");\r\n return this;\r\n }\r\n }\r\n\r\n /**\r\n * Executes a callback function once the element is fully loaded.\r\n * If the element is already loaded, the callback is called immediately.\r\n * Otherwise, a MutationObserver is used to detect when the element is added to the DOM.\r\n * @param callback A callback function to execute once the element is loaded.\r\n * Receives instance of 'this' as an argument\r\n */\r\n public onceLoaded(callback: (instance: DOMNodeReference) => any): void {\r\n if (this.isLoaded) {\r\n callback(this);\r\n return;\r\n }\r\n\r\n if (this.target instanceof HTMLElement) {\r\n callback(this);\r\n return;\r\n }\r\n const observer = new MutationObserver(\r\n function (this: DOMNodeReference) {\r\n if (document.querySelector(this.target as string)) {\r\n observer.disconnect(); // Stop observing once loaded\r\n this.isLoaded = true;\r\n callback(this); // Call the provided callback\r\n }\r\n }.bind(this)\r\n );\r\n\r\n this.eventManager!.registerObserver(observer, {\r\n nodeToObserve: document.body,\r\n options: { subtree: true, childList: true },\r\n });\r\n }\r\n}\r\n", "/********/ /********/ export default abstract class InputMask {\r\n abstract input: HTMLInputElement;\r\n\r\n constructor() {}\r\n\r\n protected abstract setupEventListeners(): void;\r\n\r\n protected abstract formatInput(): void;\r\n\r\n protected onFocus(): void {\r\n // Select all text on focus for easier editing\r\n setTimeout(() => this.input.select(), 0);\r\n }\r\n\r\n protected onBlur(): void {\r\n // Ensure proper formatting when leaving the field\r\n this.formatInput();\r\n }\r\n\r\n // Set a new numerical value\r\n public setValue(value: any): void {\r\n this.input.value = String(value);\r\n }\r\n\r\n // Destroy the mask and remove event listeners\r\n public abstract destroy(): void;\r\n}\r\n", "import InputMask from \"./InputMask.ts\";\r\n\r\ntype CountryCodeFormat = \"+\" | \"()\" | \"00\";\r\n\r\ninterface PhoneNumberMaskOptions {\r\n countryCode?: string; // The actual country code (e.g., \"1\" for US)\r\n countryCodeFormat?: CountryCodeFormat; // How to format the country code\r\n format: string; // Format for the main phone number (e.g., \"(xxx) xxx-xxxx\")\r\n}\r\n\r\nexport default class PhoneNumberMask extends InputMask {\r\n public override input: HTMLInputElement;\r\n protected options: PhoneNumberMaskOptions;\r\n\r\n constructor(\r\n inputElement: HTMLInputElement,\r\n options: Partial<PhoneNumberMaskOptions> = {}\r\n ) {\r\n super();\r\n this.input = inputElement;\r\n this.options = {\r\n format: options.format || \"(xxx) xxx-xxxx\",\r\n countryCode: options.countryCode || \"\",\r\n countryCodeFormat: options.countryCodeFormat || \"+\",\r\n };\r\n\r\n this.onFocus = this.onFocus.bind(this);\r\n this.formatInput = this.formatInput.bind(this);\r\n this.onBlur = this.onBlur.bind(this);\r\n\r\n this.setupEventListeners();\r\n\r\n // Initial formatting\r\n setTimeout(() => {\r\n this.formatInput();\r\n }, 0);\r\n }\r\n\r\n protected override setupEventListeners(): void {\r\n // Add specific handlers for phone input if needed\r\n this.input.addEventListener(\"focus\", this.onFocus);\r\n this.input.addEventListener(\"input\", this.formatInput);\r\n this.input.addEventListener(\"blur\", this.onBlur);\r\n }\r\n\r\n protected formatInput(): void {\r\n const value = this.input.value;\r\n\r\n // Store caret position\r\n const caretPosition = this.input.selectionStart || 0;\r\n const oldLength = value.length;\r\n\r\n // Allow only digits and extract them\r\n const digits = value.replace(/\\D/g, \"\");\r\n\r\n // Format according to the specified format\r\n const formattedValue = this.formatPhoneNumber(digits);\r\n\r\n // Update the input value\r\n this.input.value = formattedValue;\r\n\r\n // Adjust caret position based on the change in length\r\n const newPosition = Math.min(\r\n caretPosition + (formattedValue.length - oldLength),\r\n formattedValue.length\r\n );\r\n this.input.setSelectionRange(newPosition, newPosition);\r\n }\r\n\r\n private formatPhoneNumber(digits: string): string {\r\n if (!digits) return \"\";\r\n\r\n let phoneDigits = digits;\r\n let countryCodeValue = \"\";\r\n\r\n // Extract country code digits if a country code is specified\r\n if (this.options.countryCode) {\r\n const countryCodeLength = this.options.countryCode.length;\r\n\r\n // If we have enough digits, use them for the country code\r\n if (digits.length > countryCodeLength) {\r\n countryCodeValue = digits.substring(0, countryCodeLength);\r\n phoneDigits = digits.substring(countryCodeLength);\r\n } else {\r\n // Not enough digits for both country code and phone, prioritize country code\r\n countryCodeValue = digits;\r\n phoneDigits = \"\";\r\n }\r\n }\r\n\r\n // Format country code according to the specified format\r\n let formattedCountryCode = \"\";\r\n if (countryCodeValue) {\r\n switch (this.options.countryCodeFormat) {\r\n case \"+\":\r\n formattedCountryCode = `+${countryCodeValue} `;\r\n break;\r\n case \"()\":\r\n formattedCountryCode = `(${countryCodeValue}) `;\r\n break;\r\n case \"00\":\r\n formattedCountryCode = `00${countryCodeValue} `;\r\n break;\r\n default:\r\n formattedCountryCode = `+${countryCodeValue} `;\r\n }\r\n }\r\n\r\n // Format the main phone number\r\n let result = this.options.format;\r\n let digitIndex = 0;\r\n\r\n // Replace each 'x' in the format with a digit from phoneDigits\r\n for (let i = 0; i < result.length && digitIndex < phoneDigits.length; i++) {\r\n if (result[i] === \"x\") {\r\n result =\r\n result.substring(0, i) +\r\n phoneDigits[digitIndex++] +\r\n result.substring(i + 1);\r\n }\r\n }\r\n\r\n // Remove any remaining 'x' placeholders\r\n result = result.replace(/x/g, \"\");\r\n\r\n // Trim any extra formatting at the end if not all digits are used\r\n const lastNonFormatChar = result.split(\"\").findIndex((char, index) => {\r\n return (\r\n !/\\d/.test(char) &&\r\n result.substring(index).indexOf(\"x\") === -1 &&\r\n result.substring(index).replace(/[\\s\\-()]/g, \"\").length === 0\r\n );\r\n });\r\n\r\n if (lastNonFormatChar !== -1) {\r\n result = result.substring(0, lastNonFormatChar);\r\n }\r\n\r\n return formattedCountryCode + result;\r\n }\r\n\r\n protected override onFocus(): void {\r\n // Select all text on focus for easier editing\r\n setTimeout(() => this.input.select(), 0);\r\n }\r\n\r\n protected override onBlur(): void {\r\n // Ensure proper formatting when leaving the field\r\n this.formatInput();\r\n\r\n // If the value has too few digits, consider clearing or keeping minimal format\r\n const digits = this.getDigits();\r\n const minLength = this.options.countryCode\r\n ? 7 + this.options.countryCode.length\r\n : 7; // Minimum reasonable length\r\n\r\n if (digits.length < minLength) {\r\n // Either clear completely or maintain basic format based on UX preference\r\n // this.input.value = \"\"; // Option 1: Clear completely\r\n // Option 2: Keep partial format with what digits we have (default)\r\n }\r\n }\r\n\r\n // Get the raw digits\r\n public getDigits(): string {\r\n return this.input.value.replace(/\\D/g, \"\");\r\n }\r\n\r\n // Get country code digits separately\r\n public getCountryCode(): string {\r\n if (!this.options.countryCode) return \"\";\r\n\r\n const digits = this.getDigits();\r\n const countryCodeLength = this.options.countryCode.length;\r\n\r\n return digits.length >= countryCodeLength\r\n ? digits.substring(0, countryCodeLength)\r\n : digits;\r\n }\r\n\r\n // Get phone number digits without country code\r\n public getPhoneDigits(): string {\r\n if (!this.options.countryCode) return this.getDigits();\r\n\r\n const digits = this.getDigits();\r\n const countryCodeLength = this.options.countryCode.length;\r\n\r\n return digits.length > countryCodeLength\r\n ? digits.substring(countryCodeLength)\r\n : \"\";\r\n }\r\n\r\n // Set a new phone number value (digits only)\r\n public override setValue(digits: string): void {\r\n // Ensure we only have digits\r\n const cleanDigits = digits.replace(/\\D/g, \"\");\r\n this.input.value = this.formatPhoneNumber(cleanDigits);\r\n }\r\n\r\n // Check if the phone number has a valid length\r\n public isValid(): boolean {\r\n const phoneDigits = this.getPhoneDigits();\r\n const countryDigits = this.getCountryCode();\r\n\r\n // Check if country code is complete\r\n const isCountryCodeValid =\r\n !this.options.countryCode ||\r\n countryDigits.length === this.options.countryCode.length;\r\n\r\n // Most phone numbers have 10 digits, but this can be adjusted\r\n return isCountryCodeValid && phoneDigits.length >= 10;\r\n }\r\n\r\n public destroy(): void {\r\n this.input.removeEventListener(\"focus\", this.onFocus);\r\n this.input.removeEventListener(\"input\", this.formatInput);\r\n this.input.removeEventListener(\"blur\", this.onBlur);\r\n }\r\n}\r\n", "import type DOMNodeReference from \"./DOMNodeReference.ts\";\r\n\r\ndeclare type EventType = string;\r\ndeclare type Handler = (this: DOMNodeReference, ...args: any[]) => void;\r\ndeclare type Listeners = Set<DOMNodeReference>;\r\n\r\n/********/ /********/ export default class EventManager {\r\n private readonly events: Map<EventType, Handler> = new Map();\r\n private readonly listeners: Map<EventType, Listeners> = new Map();\r\n private readonly dependencyHandlers: Set<[DOMNodeReference, Handler]> =\r\n new Set();\r\n private observers: Array<MutationObserver | ResizeObserver> = [];\r\n private boundListeners: Array<BoundEventListener> = [];\r\n\r\n constructor() {}\r\n\r\n /********/ public dispatchDependencyHandlers(): void {\r\n for (const [dependency, handler] of this.dependencyHandlers) {\r\n handler.call(dependency);\r\n }\r\n }\r\n\r\n /********/ public registerDependent(\r\n dependency: DOMNodeReference,\r\n handler: Handler\r\n ): \"success\" | Error {\r\n try {\r\n this.dependencyHandlers.add([dependency, handler]);\r\n return \"success\";\r\n } catch {\r\n return new Error(`Failed register dependant: ${dependency.target}`);\r\n }\r\n }\r\n\r\n /********/ public registerEvent(\r\n event: EventType,\r\n handler: Handler\r\n ): \"success\" | Error {\r\n if (this.events.has(event)) {\r\n console.error(\"Event registration has already been defined for: \", event);\r\n return new Error(\r\n `Event registration has already been defined for: ${event}`\r\n );\r\n }\r\n this.listeners.set(event, new Set());\r\n this.events.set(event, handler);\r\n return \"success\";\r\n }\r\n\r\n /********/ public registerListener(\r\n event: EventType,\r\n listener: DOMNodeReference\r\n ): \"success\" | Error {\r\n if (this.events.has(event)) {\r\n const listeners: Listeners = this.listeners.get(event) ?? new Set();\r\n listeners.add(listener);\r\n this.listeners.set(event, listeners);\r\n return \"success\";\r\n } else {\r\n console.error(\"No event registration found for: \", event);\r\n return new Error(`No event registration found for: ${event}`);\r\n }\r\n }\r\n\r\n /********/ public emit(eventType: EventType, ...args: any[]): void {\r\n if (this.events.has(eventType)) {\r\n //\r\n const event: Handler = this.events.get(eventType) as Handler;\r\n const listeners: Listeners | undefined = this.listeners.get(eventType);\r\n //\r\n if (!listeners) return;\r\n //\r\n for (const listener of listeners) {\r\n event.call(listener, ...args);\r\n }\r\n //\r\n } else {\r\n console.error(\"Event not found in EventRegistry: \", eventType);\r\n }\r\n return;\r\n }\r\n\r\n /********/ public stopListening(listener: DOMNodeReference): void {\r\n for (const [_event, listeners] of this.listeners) {\r\n if (listeners.has(listener)) listeners.delete(listener);\r\n }\r\n }\r\n\r\n /********/ public registerObserver(\r\n observer: MutationObserver | ResizeObserver,\r\n observerOptions: {\r\n nodeToObserve: Element;\r\n options: Partial<ResizeObserverOptions> | Partial<MutationObserverInit>;\r\n }\r\n ): void {\r\n const { nodeToObserve, options } = observerOptions;\r\n observer.observe(nodeToObserve, options);\r\n this.observers.push(observer);\r\n }\r\n\r\n /********/ public registerDOMEventListener(\r\n element: Element,\r\n eventType: keyof HTMLElementEventMap,\r\n handler: (e: Event) => unknown\r\n ): void {\r\n element.addEventListener(eventType, handler);\r\n\r\n this.boundListeners.push({\r\n element,\r\n handler,\r\n event: eventType,\r\n });\r\n }\r\n\r\n /********/ public destroy(): void {\r\n // Remove all bound event listeners\r\n this.boundListeners?.forEach((binding) => {\r\n binding.element?.removeEventListener(binding.event, binding.handler);\r\n });\r\n this.boundListeners = []; // Clear the array\r\n\r\n // Disconnect all observers\r\n this.observers?.forEach((observer) => {\r\n observer.disconnect();\r\n });\r\n this.observers = []; // Clear the array\r\n\r\n this.events.clear();\r\n\r\n this.dependencyHandlers.clear();\r\n\r\n this.listeners.clear();\r\n }\r\n}\r\n", "import { init, destroy } from \"../constants/symbols.ts\";\r\nimport VisibilityManager from \"./VisibilityManager.ts\";\r\nimport DOMNodeReference from \"./DOMNodeReference.ts\";\r\nimport EventManager from \"./EventManager.ts\";\r\nimport ValueManager from \"./ValueManager.ts\";\r\nimport Errors from \"../errors/errors.ts\";\r\n\r\nexport default class Radio extends DOMNodeReference {\r\n // allow for indexing methods with symbols\r\n [key: symbol]: (...arg: any[]) => any;\r\n\r\n public radioType: RadioType | undefined;\r\n public declare radioParent: DOMNodeReference | undefined;\r\n\r\n constructor(\r\n parent: DOMNodeReference,\r\n target: Element | string,\r\n root: Element = document.body,\r\n timeoutMs: number,\r\n radioType: RadioType\r\n ) {\r\n super(target, root, timeoutMs);\r\n\r\n this.radioParent = parent;\r\n this.radioType = radioType;\r\n }\r\n\r\n public async [init](): Promise<void> {\r\n /**\r\n * dynamically define the s.init method using our custom symbol\r\n * this makes it so that the s.init method cannot be accessed outside\r\n * of this package: i.e. by any consumers of the package\r\n */\r\n try {\r\n await super[init]();\r\n this.initEventManager();\r\n this.initVisibilityManager();\r\n this.initValueManager();\r\n\r\n // we want to ensure that all method calls from the consumer have access to 'this'\r\n this._bindMethods();\r\n\r\n // when the element is removed from the DOM, destroy this\r\n const observer = new MutationObserver((mutations) => {\r\n for (const mutation of mutations) {\r\n if (Array.from(mutation.removedNodes).includes(this.element)) {\r\n this[destroy]();\r\n observer.disconnect();\r\n break;\r\n }\r\n }\r\n });\r\n\r\n observer.observe(document.body, {\r\n childList: true,\r\n subtree: true,\r\n });\r\n\r\n DOMNodeReference.instances.push(this);\r\n\r\n this.isLoaded = true;\r\n } catch (error) {\r\n const errorMessage: string =\r\n error instanceof Error ? error.message : String(error);\r\n throw new Errors.InitializationError(this, errorMessage);\r\n }\r\n }\r\n\r\n protected override initEventManager(): void {\r\n this.eventManager = new EventManager();\r\n }\r\n\r\n protected override initValueManager(): void {\r\n this.valueManager = new ValueManager(this);\r\n\r\n this._valueSync();\r\n }\r\n\r\n protected override initVisibilityManager(): void {\r\n this.visibilityManager = new VisibilityManager(this.element);\r\n }\r\n\r\n override [destroy](): void {\r\n super[destroy]();\r\n this.radioParent = undefined;\r\n this.radioType = undefined;\r\n }\r\n}\r\n", "import PowerPagesElement from \"../core/PowerPagesElement.ts\";\r\nimport type DOMNodeReference from \"./DOMNodeReference.ts\";\r\nimport Radio from \"./Radio.ts\";\r\n\r\nexport default class ValueManager {\r\n public value: any;\r\n public checked: true | false = false;\r\n public element: HTMLElement | null;\r\n private noRadio: Radio | undefined;\r\n private yesRadio: Radio | undefined;\r\n public radioParent?: DOMNodeReference | undefined;\r\n private isRadio: boolean = false;\r\n private radioType: RadioType | undefined;\r\n\r\n constructor(instance: DOMNodeReference) {\r\n if (instance instanceof PowerPagesElement) {\r\n this.noRadio = instance.noRadio;\r\n this.yesRadio = instance.yesRadio;\r\n this.radioParent = undefined;\r\n } else if (instance instanceof Radio) {\r\n this.isRadio = true;\r\n this.noRadio = undefined;\r\n this.yesRadio = undefined;\r\n this.radioParent = instance.radioParent;\r\n this.radioType = instance.radioType;\r\n }\r\n\r\n this.element = instance.element;\r\n }\r\n\r\n public setValue(value: any): void {\r\n const validatedValue = this._validateValue(value);\r\n\r\n if (this.yesRadio instanceof Radio && this.noRadio instanceof Radio) {\r\n (this.yesRadio.element as HTMLInputElement).checked = Boolean(value);\r\n (this.noRadio.element as HTMLInputElement).checked = Boolean(!value);\r\n this.value = value;\r\n (this.element as HTMLInputElement).checked = Boolean(value);\r\n (this.element as HTMLInputElement).value = value;\r\n } else if (\r\n this.isRadio ||\r\n (this.element as HTMLInputElement).type === \"radio\"\r\n ) {\r\n (this.element as HTMLInputElement).checked = value;\r\n this.checked = value;\r\n this.value = value;\r\n this.radioParent?.updateValue();\r\n } else {\r\n (this.element as HTMLInputElement).value = validatedValue;\r\n this.value = validatedValue;\r\n }\r\n }\r\n\r\n public async updateValue(e?: Event): Promise<void> {\r\n if (e) {\r\n e.stopPropagation();\r\n }\r\n\r\n const elementValue = await this.getElementValue();\r\n this.value = elementValue.value;\r\n\r\n if (elementValue.checked !== undefined) {\r\n this.checked = elementValue.checked;\r\n }\r\n\r\n // need a way to make sure radios stay in sync with each-other. If yes is checked, no should be 'unchecked' and vise-versa\r\n if (\r\n this.radioParent instanceof PowerPagesElement &&\r\n e &&\r\n e.type !== \"manual-radio-sync\"\r\n ) {\r\n switch (this.radioType) {\r\n case \"falsy\":\r\n this.radioParent.yesRadio!.setValue(!elementValue);\r\n await this.radioParent.yesRadio!.updateValue(\r\n new Event(\"manual-radio-sync\")\r\n );\r\n\r\n break;\r\n case \"truthy\":\r\n this.radioParent.noRadio!.setValue(!elementValue);\r\n await this.radioParent.noRadio!.updateValue(\r\n new Event(\"manual-radio-sync\")\r\n );\r\n\r\n break;\r\n }\r\n\r\n this.radioParent.updateValue();\r\n }\r\n }\r\n\r\n public getElementValue(): Promise<ElementValue> {\r\n return new Promise((resolve) => {\r\n const input = this.element as HTMLInputElement;\r\n const select = this.element as HTMLSelectElement;\r\n\r\n if (this.yesRadio instanceof Radio && this.noRadio instanceof Radio) {\r\n resolve({\r\n value: this.yesRadio.checked,\r\n checked: this.yesRadio.checked,\r\n });\r\n }\r\n\r\n let returnValue: ElementValue = {\r\n value: null,\r\n };\r\n switch (input.type) {\r\n case \"checkbox\":\r\n case \"radio\":\r\n resolve({\r\n value: input.checked,\r\n checked: input.checked,\r\n });\r\n break;\r\n case \"select-multiple\":\r\n resolve({\r\n value: Array.from(select.selectedOptions).map(\r\n (option) => option.value\r\n ),\r\n });\r\n break;\r\n\r\n case \"select-one\":\r\n resolve({\r\n value: select.value,\r\n });\r\n break;\r\n\r\n case \"number\":\r\n resolve({\r\n value: input.value !== \"\" ? Number(input.value) : null,\r\n });\r\n break;\r\n\r\n default: {\r\n let cleanValue: string | number = input.value;\r\n if (this.element!.classList.contains(\"decimal\")) {\r\n cleanValue = parseFloat(input.value.replace(/[$,]/g, \"\").trim());\r\n }\r\n\r\n returnValue = {\r\n value: cleanValue,\r\n };\r\n }\r\n }\r\n\r\n returnValue = {\r\n ...returnValue,\r\n value: this._validateValue(returnValue.value),\r\n };\r\n\r\n resolve(returnValue);\r\n });\r\n }\r\n\r\n protected _validateValue(value: any): any {\r\n if (typeof value === \"boolean\" || value === \"true\" || value === \"false\") {\r\n return value === true || value === \"true\";\r\n }\r\n\r\n // If it's a select element or text input (not decimal), return as is\r\n if (\r\n this.element instanceof HTMLSelectElement ||\r\n ((this.element as HTMLInputElement).type === \"text\" &&\r\n !(this.element as HTMLInputElement).classList.contains(\"decimal\"))\r\n ) {\r\n return value;\r\n }\r\n\r\n // Handle null/empty cases\r\n if (value === null || value === \"\") {\r\n return value;\r\n }\r\n\r\n if (!isNaN(Number(value))) {\r\n return Number(value);\r\n }\r\n\r\n return value;\r\n }\r\n\r\n public clearValue(): void {\r\n try {\r\n const element = this.element;\r\n\r\n // set 'default value' // effects date inputs primarily\r\n (element as HTMLInputElement).defaultValue = \"\";\r\n\r\n if (element instanceof HTMLInputElement) {\r\n switch (element.type.toLowerCase()) {\r\n case \"checkbox\":\r\n case \"radio\":\r\n element.checked = false;\r\n this.checked = false;\r\n this.value = false;\r\n break;\r\n\r\n case \"number\":\r\n element.value = \"\";\r\n this.value = null;\r\n break;\r\n\r\n default: // handles text, email, tel, etc.\r\n element.value = \"\";\r\n this.value = null;\r\n break;\r\n }\r\n } else if (element instanceof HTMLSelectElement) {\r\n if (element.multiple) {\r\n Array.from(element.options).forEach(\r\n (option) => (option.selected = false)\r\n );\r\n this.value = null;\r\n } else {\r\n element.selectedIndex = -1;\r\n this.value = null;\r\n }\r\n } else if (element instanceof HTMLTextAreaElement) {\r\n element.value = \"\";\r\n this.value = null;\r\n } else {\r\n this.value = null;\r\n }\r\n } catch (error) {\r\n const errorMessage = `Failed to clear values for element with target \"${this}\": ${\r\n error instanceof Error ? error.message : String(error)\r\n }`;\r\n throw new Error(errorMessage);\r\n }\r\n }\r\n\r\n public destroy(): void {\r\n this.value = null;\r\n this.checked = false;\r\n this.element = null;\r\n this.noRadio = undefined;\r\n this.yesRadio = undefined;\r\n this.isRadio = false;\r\n }\r\n}\r\n", "import InputMask from \"./InputMask.ts\";\r\n\r\ninterface MoneyInputMaskOptions extends InputMaskOptions {\r\n prefix: CurrencySymbol; // Currency symbol (e.g., \"$\")\r\n decimalPlaces: number; // Number of decimal places (default: 2)\r\n thousandsSeparator: string; // Character for separating thousands (e.g., \",\")\r\n decimalSeparator: string; // Character for decimal point (e.g., \".\")\r\n allowNegative: boolean; // Whether to allow negative values\r\n}\r\n\r\nexport default class MoneyMask extends InputMask {\r\n public input: HTMLInputElement;\r\n protected options: MoneyInputMaskOptions;\r\n private buffer: string = \"\";\r\n private charAtSelection: string | undefined = \"\";\r\n private charBeforeSelection: string | undefined = \"\";\r\n private lengthOf0FormattedValue: number;\r\n // Cache regex patterns\r\n private readonly digitRegex = /\\d/;\r\n private readonly nonDigitRegex = /\\D/g;\r\n private readonly thousandsRegex = /\\B(?=(\\d{3})+(?!\\d))/g;\r\n private readonly separatorRegex: RegExp;\r\n\r\n constructor(\r\n inputElement: HTMLInputElement,\r\n options: Partial<MoneyInputMaskOptions> = {}\r\n ) {\r\n super();\r\n this.input = inputElement;\r\n this.options = {\r\n prefix: options.prefix || \"$\",\r\n decimalPlaces: options.decimalPlaces ?? 2,\r\n thousandsSeparator: options.thousandsSeparator || \",\",\r\n decimalSeparator: options.decimalSeparator || \".\",\r\n allowNegative: options.allowNegative ?? true,\r\n };\r\n\r\n // Create escaped separator regex once during initialization\r\n const escapedThousands = this.escapeRegExp(this.options.thousandsSeparator);\r\n const escapedDecimal = this.escapeRegExp(this.options.decimalSeparator);\r\n this.separatorRegex = new RegExp(`[${escapedThousands}${escapedDecimal}]`);\r\n\r\n // Bind methods once\r\n this.onFocus = this.onFocus.bind(this);\r\n this.onInput = this.onInput.bind(this);\r\n this.onSelectionChange = this.onSelectionChange.bind(this);\r\n this.onBlur = this.onBlur.bind(this);\r\n\r\n // Calculate zero value length once\r\n this.lengthOf0FormattedValue = `0${\r\n this.options.decimalPlaces > 0\r\n ? this.options.decimalSeparator + \"0\".repeat(this.options.decimalPlaces)\r\n : \"\"\r\n }`.length;\r\n\r\n this.setupEventListeners();\r\n\r\n // Initialize with existing value if present\r\n if (this.input.value) {\r\n this.buffer = this.input.value.replace(this.nonDigitRegex, \"\");\r\n }\r\n\r\n // Initial formatting\r\n this.formatAndDisplay();\r\n }\r\n\r\n private escapeRegExp(string: string): string {\r\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n }\r\n\r\n private formatAndDisplay(): void {\r\n const numericValue = Number(this.buffer || \"0\");\r\n this.input.value = this.formatNumber(numericValue);\r\n }\r\n\r\n protected override setupEventListeners(): void {\r\n this.input.addEventListener(\"focus\", this.onFocus);\r\n this.input.addEventListener(\"input\", this.onInput);\r\n this.input.addEventListener(\"selectionchange\", this.onSelectionChange);\r\n this.input.addEventListener(\"blur\", this.onBlur);\r\n }\r\n\r\n protected formatInput(): void {\r\n const value = this.input.value;\r\n const caretPosition = this.input.selectionStart || 0;\r\n const oldLength = value.length;\r\n\r\n // Create allowed characters pattern only when needed\r\n const allowedPattern = new RegExp(\r\n `[^0-9${this.options.decimalSeparator}${\r\n this.options.allowNegative ? \"-\" : \"\"\r\n }]`,\r\n \"g\"\r\n );\r\n\r\n let cleanValue = value.replace(allowedPattern, \"\");\r\n\r\n // Ensure only one decimal separator\r\n const parts = cleanValue.split(this.options.decimalSeparator);\r\n if (parts.length > 2) {\r\n cleanValue =\r\n parts[0] + this.options.decimalSeparator + parts.slice(1).join(\"\");\r\n }\r\n\r\n // Handle negative sign\r\n if (this.options.allowNegative && cleanValue.indexOf(\"-\") > 0) {\r\n cleanValue = cleanValue.replace(/-/g, \"\");\r\n if (cleanValue.charAt(0) !== \"-\") {\r\n cleanValue = \"-\" + cleanValue;\r\n }\r\n }\r\n\r\n // Convert to number and format\r\n let numericValue: number;\r\n if (cleanValue === \"\" || cleanValue === \"-\") {\r\n numericValue = 0;\r\n } else {\r\n numericValue = parseFloat(\r\n cleanValue.replace(this.options.decimalSeparator, \".\")\r\n );\r\n }\r\n\r\n if (isNaN(numericValue)) {\r\n numericValue = 0;\r\n }\r\n\r\n // Format the number\r\n const formattedValue = this.formatNumber(numericValue);\r\n\r\n // Update the input value\r\n this.input.value = formattedValue;\r\n\r\n // Adjust caret position\r\n const newPosition = caretPosition + (formattedValue.length - oldLength);\r\n this.input.setSelectionRange(newPosition, newPosition);\r\n }\r\n\r\n protected formatNumber(value: number): string {\r\n const adjustedValue = value / 10 ** this.options.decimalPlaces;\r\n const isNegative = adjustedValue < 0;\r\n const absoluteValue = Math.abs(adjustedValue);\r\n\r\n // Format with fixed decimal places\r\n const formatted = absoluteValue.toFixed(this.options.decimalPlaces);\r\n const [integerPart, decimalPart] = formatted.split(\".\");\r\n\r\n // Add thousands separators\r\n const formattedInteger = integerPart.replace(\r\n this.thousandsRegex,\r\n this.options.thousandsSeparator\r\n );\r\n\r\n // Combine parts\r\n return (\r\n (isNegative ? \"-\" : \"\") +\r\n this.options.prefix +\r\n formattedInteger +\r\n (this.options.decimalPlaces > 0\r\n ? this.options.decimalSeparator + decimalPart\r\n : \"\")\r\n );\r\n }\r\n\r\n protected onSelectionChange(_e: Event): void {\r\n const position = this.input.selectionStart as number;\r\n this.charAtSelection = this.input.value[position];\r\n this.charBeforeSelection = this.input.value[position - 1];\r\n }\r\n\r\n protected onInput(_e: Event): void {\r\n const e = _e as InputEvent;\r\n const formattedValue: string = this.input.value;\r\n const caretPosition: number = this.input.selectionStart ?? 0;\r\n\r\n // Calculate the raw index: count only digits before the caret\r\n const rawIndex = formattedValue\r\n .slice(0, caretPosition)\r\n .replace(this.nonDigitRegex, \"\").length;\r\n\r\n let newRawIndex = rawIndex;\r\n\r\n switch (e.inputType) {\r\n case \"insertText\":\r\n // Handle text insertion\r\n this.buffer =\r\n this.buffer.slice(0, rawIndex - 1) +\r\n (e.data || \"\").replace(this.nonDigitRegex, \"\") +\r\n this.buffer.slice(rawIndex - 1);\r\n\r\n newRawIndex = rawIndex;\r\n break;\r\n\r\n case \"deleteContentBackward\":\r\n // Handle backspace\r\n if (rawIndex >= 0) {\r\n if (this.separatorRegex.test(this.charBeforeSelection as string)) {\r\n this.buffer =\r\n this.buffer.slice(0, rawIndex - 1) + this.buffer.slice(rawIndex);\r\n newRawIndex = rawIndex - 1;\r\n } else {\r\n this.buffer =\r\n this.buffer.slice(0, rawIndex) + this.buffer.slice(rawIndex + 1);\r\n newRawIndex = rawIndex;\r\n }\r\n } else if (formattedValue === \"\") {\r\n this.buffer = \"\";\r\n }\r\n break;\r\n\r\n case \"deleteContentForward\":\r\n // Handle delete key\r\n if (rawIndex < this.buffer.length) {\r\n this.buffer =\r\n this.buffer.slice(0, rawIndex) + this.buffer.slice(rawIndex + 1);\r\n }\r\n break;\r\n\r\n case \"deleteWordBackward\":\r\n case \"deleteWordForward\":\r\n // Handle word deletion\r\n this.buffer = \"\";\r\n newRawIndex = this.lengthOf0FormattedValue;\r\n break;\r\n\r\n default:\r\n // Fallback for other input types\r\n this.buffer = formattedValue.replace(this.nonDigitRegex, \"\");\r\n newRawIndex = this.buffer.length;\r\n }\r\n\r\n // Format and update the display\r\n const numericValue = Number(this.buffer || \"0\");\r\n const newFormattedValue = this.formatNumber(numericValue);\r\n this.input.value = newFormattedValue;\r\n\r\n // Update caret position\r\n const newCaretPosition = this.mapRawIndexToFormattedPosition(\r\n newRawIndex,\r\n newFormattedValue\r\n );\r\n\r\n this.input.setSelectionRange(newCaretPosition, newCaretPosition);\r\n }\r\n\r\n private mapRawIndexToFormattedPosition(\r\n rawIndex: number,\r\n formatted: string\r\n ): number {\r\n let digitCount = 0;\r\n for (let i = 0; i < formatted.length; i++) {\r\n if (this.digitRegex.test(formatted[i])) {\r\n digitCount++;\r\n }\r\n if (digitCount === rawIndex) {\r\n return i + 1;\r\n }\r\n }\r\n return formatted.length;\r\n }\r\n\r\n protected override onFocus(): void {\r\n // Debounce selection to avoid race conditions\r\n setTimeout(() => this.input.select(), 0);\r\n }\r\n\r\n protected override onBlur(): void {\r\n // Format on blur\r\n const numericValue = Number(this.buffer || \"0\");\r\n this.input.value = this.formatNumber(numericValue);\r\n\r\n // Reset to zero if needed\r\n if (numericValue === 0) {\r\n this.buffer = \"\";\r\n const zeros = \"0\".repeat(this.options.decimalPlaces);\r\n this.input.value = `${this.options.prefix}0${\r\n this.options.decimalPlaces > 0\r\n ? this.options.decimalSeparator + zeros\r\n : \"\"\r\n }`;\r\n }\r\n }\r\n\r\n // Get the numerical value\r\n public getNumericalValue(): number {\r\n return Number(this.buffer || \"0\") / 10 ** this.options.decimalPlaces;\r\n }\r\n\r\n // Set a new numerical value\r\n public override setValue(value: number): void {\r\n const scaledValue = Math.round(\r\n Math.abs(value) * 10 ** this.options.decimalPlaces\r\n );\r\n\r\n this.buffer = scaledValue.toString();\r\n this.input.value = this.formatNumber(scaledValue);\r\n }\r\n\r\n public destroy(): void {\r\n this.input.removeEventListener(\"focus\", this.onFocus);\r\n this.input.removeEventListener(\"input\", this.onInput);\r\n this.input.removeEventListener(\"selectionchange\", this.onSelectionChange);\r\n this.input.removeEventListener(\"blur\", this.onBlur);\r\n }\r\n}\r\n", "import VisibilityManager from \"../ancillary/VisibilityManager.ts\";\r\nimport DOMNodeReference from \"../ancillary/DOMNodeReference.ts\";\r\nimport PhoneNumberMask from \"../utils/PhoneNumberMask.ts\";\r\nimport EventManager from \"../ancillary/EventManager.ts\";\r\nimport ValueManager from \"../ancillary/ValueManager.ts\";\r\nimport { init, destroy } from \"../constants/symbols.ts\";\r\nimport type InputMask from \"../utils/InputMask.ts\";\r\nimport MoneyInputMask from \"../utils/MoneyMask.ts\";\r\nimport Radio from \"../ancillary/Radio.ts\";\r\nimport Errors from \"../errors/errors.ts\";\r\n\r\n/********/ /********/ export default class PowerPagesElement extends DOMNodeReference {\r\n // allow for indexing methods with symbols\r\n [key: symbol]: (...arg: any[]) => any;\r\n private isMasked: boolean = false;\r\n\r\n /**\r\n * Represents the 'yes' option of a boolean radio field.\r\n * This property is only available when the parent node\r\n * is a main field for a boolean radio input.\r\n */\r\n public yesRadio: Radio | undefined;\r\n /**\r\n * Represents the 'no' option of a boolean radio field.\r\n * This property is only available when the parent node\r\n * is a main field for a boolean radio input.\r\n */\r\n public noRadio: Radio | undefined;\r\n\r\n /**\r\n * Creates an instance of PowerPagesElement.\r\n * @param target - The CSS selector to find the desired DOM element.\r\n * @param root - Optionally specify the element within to search for the element targeted by 'target'\r\n * Defaults to 'document.body'\r\n */\r\n /******/ constructor(\r\n target: Element | string,\r\n root: Element = document.body,\r\n timeoutMs: number\r\n ) {\r\n super(target, root, timeoutMs);\r\n }\r\n\r\n //\r\n public async [init](): Promise<void> {\r\n /**\r\n * dynamically define the s.init method using our custom symbol\r\n * this makes it so that the s.init method cannot be accessed outside\r\n * of this package: i.e. by any consumers of the package\r\n */\r\n try {\r\n await super[init]();\r\n\r\n if (\r\n this.element.id &&\r\n this.element.querySelectorAll(\r\n `#${this.element.id} > input[type=\"radio\"]`\r\n ).length > 0\r\n ) {\r\n await this._attachRadioButtons();\r\n }\r\n\r\n this.initEventManager();\r\n this.initVisibilityManager();\r\n this.initValueManager();\r\n\r\n // we want to ensure that all method calls from the consumer have access to 'this'\r\n this._bindMethods();\r\n\r\n // when the element is removed from the DOM, destroy this\r\n const observer = new MutationObserver((mutations) => {\r\n for (const mutation of mutations) {\r\n if (Array.from(mutation.removedNodes).includes(this.element)) {\r\n if (typeof this[destroy] === \"function\") this[destroy]();\r\n observer.disconnect();\r\n break;\r\n }\r\n }\r\n });\r\n\r\n observer.observe(document.body, {\r\n childList: true,\r\n subtree: true,\r\n });\r\n\r\n PowerPagesElement.instances.push(this);\r\n\r\n this.isLoaded = true;\r\n } catch (error) {\r\n const errorMessage: string =\r\n error instanceof Error ? error.message : String(error);\r\n throw new Errors.InitializationError(this, errorMessage);\r\n }\r\n }\r\n\r\n protected override initValueManager(): void {\r\n this.valueManager = new ValueManager(this);\r\n\r\n this._valueSync();\r\n }\r\n protected override initVisibilityManager(): void {\r\n this.visibilityManager = new VisibilityManager(this.element);\r\n }\r\n protected override initEventManager(): void {\r\n this.eventManager = new EventManager();\r\n }\r\n\r\n protected async _attachRadioButtons(): Promise<void> {\r\n if (!this.element) {\r\n console.error(\r\n \"'this.element' not found: cannot attach radio buttons for \",\r\n this.target\r\n );\r\n return;\r\n }\r\n\r\n this.yesRadio = new Radio(\r\n this,\r\n 'input[type=\"radio\"][value=\"1\"]',\r\n this.element,\r\n 0,\r\n \"truthy\"\r\n );\r\n\r\n this.noRadio = new Radio(\r\n this,\r\n 'input[type=\"radio\"][value=\"0\"]',\r\n this.element,\r\n 0,\r\n \"falsy\"\r\n );\r\n\r\n await this.yesRadio[init]();\r\n await this.noRadio[init]();\r\n }\r\n\r\n public override clearValue(): void {\r\n // Handle radio button group if present\r\n if (this.yesRadio instanceof Radio && this.noRadio instanceof Radio) {\r\n this.yesRadio.clearValue();\r\n this.noRadio.clearValue();\r\n }\r\n super.clearValue();\r\n }\r\n\r\n /**\r\n * Unchecks both the yes and no radio buttons if they exist.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public uncheckRadios(): PowerPagesElement {\r\n if (\r\n this.yesRadio instanceof DOMNodeReference &&\r\n this.noRadio instanceof DOMNodeReference\r\n ) {\r\n (this.yesRadio.element as HTMLInputElement).checked = false;\r\n (this.noRadio.element as HTMLInputElement).checked = false;\r\n } else {\r\n console.error(\r\n \"[SYNACT] Attempted to uncheck radios for an element that has no radios\"\r\n );\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Apply an input mask to this element\r\n * @param type The type of input mask to apply to this element\r\n * @param options The options to specify the behavior of the mask\r\n */\r\n public inputMask(type: \"phone\" | \"money\", options: InputMaskOptions): void;\r\n public inputMask(\r\n type: \"phone\",\r\n options?: {\r\n format?: PhoneNumberFormats;\r\n countryCode?: CountryCodeFormats;\r\n }\r\n ): void;\r\n public inputMask(\r\n type: \"money\",\r\n options?: {\r\n prefix?: CurrencySymbol; // Currency symbol (e.g., \"$\")\r\n decimalPlaces?: number; // Number of decimal places (default: 2)\r\n thousandsSeparator?: string; // Character for separating thousands (e.g., \",\")\r\n decimalSeparator?: string; // Character for decimal point (e.g., \".\")\r\n allowNegative?: boolean; // Whether to allow negative values\r\n }\r\n ): void;\r\n public inputMask(\r\n type: \"money\" | \"phone\",\r\n options: InputMaskOptions\r\n ): PowerPagesElement {\r\n if (this.isMasked) {\r\n throw new Error(\r\n `You cannot apply multiple input masks to the same element. @${this.target}`\r\n );\r\n }\r\n\r\n let newMask: InputMask;\r\n switch (type) {\r\n case \"money\":\r\n newMask = new MoneyInputMask(this.element as HTMLInputElement, options);\r\n break;\r\n case \"phone\":\r\n newMask = new PhoneNumberMask(\r\n this.element as HTMLInputElement,\r\n options\r\n );\r\n break;\r\n default:\r\n throw new Error(\r\n `No type provided for 'inputMask()' at: ${this.target}`\r\n );\r\n }\r\n\r\n this.valueManager!.element = newMask.input;\r\n this.isMasked = true;\r\n\r\n return this;\r\n }\r\n\r\n protected [destroy](): void {\r\n super[destroy]();\r\n // Destroy radio buttons if they exist\r\n this.yesRadio?.[destroy]();\r\n this.noRadio?.[destroy]();\r\n this.yesRadio = undefined;\r\n this.noRadio = undefined;\r\n }\r\n}\r\n", "import type PowerPagesElement from \"./PowerPagesElement.ts\";\r\n\r\nexport default class PowerPagesElementArray extends Array<PowerPagesElement> {\r\n /**\r\n * Hides all the containers of the PowerPagesElement instances in the array.\r\n */\r\n hideAll(this: PowerPagesElementArray) {\r\n this.forEach((instance: PowerPagesElement) => instance.hide());\r\n return this;\r\n }\r\n\r\n /**\r\n * Shows all the containers of the PowerPagesElement instances in the array.\r\n */\r\n\r\n showAll(this: PowerPagesElementArray) {\r\n this.forEach((instance: PowerPagesElement) => instance.show());\r\n return this;\r\n }\r\n}\r\n", "import PowerPagesElementArray from \"../core/PowerPagesElementArray.ts\";\r\nimport type PowerPagesElement from \"../core/PowerPagesElement.ts\";\r\n\r\n/**\r\n *\r\n * @param array An array of PowerPagesElements to be modified with custom methods, as well as a custom getter. Custom getter allows for accessing properties within the array with bracket-style property access. See example\r\n * @example\r\n * ```javascript\r\n * const enhanced = enhanceArray(basicArray)\r\n * const someProp = enhanced['some_prop_logical_name']\r\n * ```\r\n */\r\nexport default function enhanceArray<T extends string>(\r\n array: PowerPagesElement[]\r\n): PowerPagesElementArray & Record<T, PowerPagesElement> {\r\n const enhancedArray = new PowerPagesElementArray(...array);\r\n\r\n return new Proxy(enhancedArray, {\r\n get(target, prop: string | symbol, receiver) {\r\n // Preserve existing array methods\r\n if (prop in target) {\r\n return Reflect.get(target, prop, receiver);\r\n }\r\n\r\n // Ensure `prop` is a string and search by `element.id`\r\n if (typeof prop === \"string\") {\r\n return target.find(\r\n (instance) =>\r\n instance.target.toString().replace(/[#\\[\\]]/g, \"\") === prop ||\r\n instance.logicalName === prop\r\n );\r\n }\r\n\r\n return undefined;\r\n },\r\n }) as PowerPagesElementArray & Record<T, PowerPagesElement>;\r\n}\r\n", "import type PowerPagesElementArray from \"./PowerPagesElementArray.ts\";\r\nimport PowerPagesElement from \"./PowerPagesElement.ts\";\r\nimport enhanceArray from \"../utils/enhanceArray.ts\";\r\nimport waitFor from \"./waitFor.ts\";\r\nimport { init } from \"../constants/symbols.ts\";\r\n\r\n// Add function overloads to clearly specify return types based on the 'multiple' parameter\r\n/**\r\n * Creates and initializes a PowerPagesElement instance.\r\n * @see {@link CreationOptions}\r\n * @param **target** - The selector, using `querySelector` syntax, for the desired DOM element. Or, the `HTMLElement` itself for which to create a PowerPagesElement.\r\n * @param **options** - Options for advanced retrieval of elements\r\n * @param **options.multiple** - Should this call return an array of instantiated references, or just a single? Defaults to false, returning a single instance\r\n * @param **options.root** - Optionally specify the element within to search for the element targeted by 'target'. Defaults to `document.body`\r\n * @param **options.timeoutMs** - Optionally specify the amount of time that should be waited to find the targeted element before throwing error - useful for async DOM loading. Relies on MutationObserver. ***WARNING***: Implementing multiple references with timeout can result in infinite loading.\r\n * @returns A promise that resolves to a Proxy of the initialized PowerPagesElement instance.\r\n *\r\n * @see {@link PowerPagesElement}\r\n * @see {@link PowerPagesElementArray}\r\n * @see {@link enhanceArray}\r\n */\r\n\r\nexport default async function createPowerPagesElement(\r\n target: string | Element\r\n): Promise<PowerPagesElement>;\r\nexport default async function createPowerPagesElement(\r\n target: Element\r\n): Promise<PowerPagesElement>;\r\nexport default async function createPowerPagesElement(\r\n target: string,\r\n options?: {\r\n /**\r\n * Optionally specify the element within which to search for the element targeted by 'target'.\r\n * Defaults to 'document.body'.\r\n */\r\n root?: HTMLElement;\r\n /**\r\n * Optionally specify the amount of time that should be waited to find the targeted element before throwing an error.\r\n * Useful for async DOM loading. Relies on MutationObserver.\r\n * WARNING: Implementing multiple references with timeout can result in infinite loading.\r\n */\r\n timeoutMs?: number;\r\n }\r\n): Promise<PowerPagesElement>;\r\n\r\nexport default async function createPowerPagesElement(\r\n target: string,\r\n options?: {\r\n /**\r\n * Should this call return an array of instantiated references, or just a single?\r\n * Defaults to false, returning a single instance.\r\n */\r\n multiple?: true;\r\n /**\r\n * Optionally specify the element within which to search for the element targeted by 'target'.\r\n * Defaults to 'document.body'.\r\n */\r\n root?: HTMLElement;\r\n /**\r\n * Optionally specify the amount of time that should be waited to find the targeted element before throwing an error.\r\n * Useful for async DOM loading. Relies on MutationObserver.\r\n * WARNING: Implementing multiple references with timeout can result in infinite loading.\r\n */\r\n timeoutMs?: number;\r\n }\r\n): Promise<PowerPagesElementArray>;\r\n\r\nexport default async function createPowerPagesElement(\r\n target: Element | string,\r\n options: CreationOptions = {\r\n multiple: false,\r\n root: document.body,\r\n timeoutMs: 0,\r\n }\r\n): Promise<PowerPagesElement | PowerPagesElementArray> {\r\n try {\r\n if (typeof options !== \"object\") {\r\n throw new TypeError(\r\n `'options' must be of type 'object'. Received type: '${typeof options}'`\r\n );\r\n }\r\n\r\n validateOptions(options);\r\n const { multiple = false, root = document.body, timeoutMs = 0 } = options;\r\n\r\n // Evaluate multiple parameter once at the start\r\n const isMultiple = typeof multiple === \"function\" ? multiple() : multiple;\r\n\r\n if (isMultiple) {\r\n if (typeof target !== \"string\") {\r\n throw new TypeError(\r\n `'target' must be of type 'string' if 'multiple' is set to 'true'. Received type: '${typeof target}'`\r\n );\r\n }\r\n\r\n const elements = <HTMLElement[]>(\r\n await waitFor(target, root, true, timeoutMs)\r\n );\r\n\r\n // Avoid recursive call with multiple flag for better performance\r\n const initializedElements = <PowerPagesElementArray>await Promise.all(\r\n elements.map(async (element) => {\r\n const instance = new PowerPagesElement(element, root, timeoutMs);\r\n await instance[init]();\r\n return new Proxy(instance, createProxyHandler());\r\n })\r\n );\r\n return enhanceArray(initializedElements);\r\n }\r\n\r\n const instance = new PowerPagesElement(target, root, timeoutMs);\r\n await instance[init]();\r\n return new Proxy(instance, createProxyHandler());\r\n } catch (error) {\r\n if (error instanceof Error) throw error;\r\n else throw new Error(\"Failed to get DOM Node by target: \" + target);\r\n }\r\n}\r\n\r\nexport function validateOptions(options: Partial<CreationOptions>) {\r\n const { multiple = false, root = document.body, timeoutMs = 0 } = options;\r\n if (typeof multiple !== \"boolean\" && typeof multiple !== \"function\") {\r\n throw new TypeError(\r\n `'multiple' must be of type 'boolean' or 'function'. Received type: '${typeof multiple}'`\r\n );\r\n }\r\n if (typeof multiple === \"function\") {\r\n const value = multiple();\r\n if (typeof value !== \"boolean\") {\r\n throw new TypeError(\r\n `'multiple' function must return a boolean. Received type: '${typeof value}'`\r\n );\r\n }\r\n }\r\n if (!(root instanceof HTMLElement)) {\r\n throw new TypeError(\r\n `'root' must be of type 'HTMLElement'. Received type: '${typeof root}'`\r\n );\r\n }\r\n if (typeof timeoutMs !== \"number\") {\r\n throw new TypeError(\r\n `'timeout' must be of type 'number'. Received type: '${typeof timeoutMs}'`\r\n );\r\n }\r\n return;\r\n}\r\n\r\n// Separate proxy handler for reusability\r\nexport function createProxyHandler() {\r\n return {\r\n get: (target: PowerPagesElement, prop: string | symbol) => {\r\n if (prop.toString().startsWith(\"_\")) return undefined;\r\n\r\n const value = target[<keyof PowerPagesElement>prop];\r\n if (typeof value === \"function\" && prop !== \"onceLoaded\") {\r\n return (...args: any[]) => {\r\n target.onceLoaded(() => value.apply(target, args));\r\n return target;\r\n };\r\n }\r\n return value;\r\n },\r\n };\r\n}\r\n", "import type PowerPagesElementArray from \"./PowerPagesElementArray.ts\";\r\nimport type PowerPagesElement from \"./PowerPagesElement.ts\";\r\nimport enhanceArray from \"../utils/enhanceArray.ts\";\r\nimport get from \"./getPowerPagesElement.ts\";\r\nimport API from \"./API.ts\";\r\n\r\n/**\r\n * When loading into a page in PowerPages that has a form,\r\n * you can use this function by passing in the GUID of the form, and you will receive an array/record\r\n * of {@link PowerPagesElement}s that represent all fields, sections, sub-grids, and tabs of the given form.\r\n * Access these properties of the {@link BoundForm} using the logical name of the control you need to access: form['logical_name']\r\n * you can then execute all the methods available from PowerPagesElement\r\n * @param formId - The string GUID of the form you want to bind to\r\n * @returns An array of PowerPagesElements, accessible as properties of a Record<string, PowerPagesElement> i.e. formProp = form[\"some_logicalName\"]\r\n * @example\r\n * ```js\r\n * bindForm(\"form-guid-0000\").then((form) => {\r\n * //...use the form\r\n * const field = form[\"field_logical_name\"]\r\n * // or\r\n * form[\"other_logical_name\"].someMethod()\r\n * })\r\n *\r\n * // or\r\n *\r\n * const form = await bindForm(\"form-guid-0000\")\r\n * ```\r\n * @see {@link BoundForm}\r\n * @see {@link PowerPagesElement}\r\n */\r\nexport default async function bindForm(\r\n formId: string\r\n): Promise<PowerPagesElementArray & Record<string, PowerPagesElement>> {\r\n try {\r\n const form = await API.getRecord<Form>(\"systemforms\", formId);\r\n const { formxml } = form;\r\n\r\n /**\r\n * since the form is coming in as a string containing XML\r\n * We have to set up a parser to extract the information we need\r\n */\r\n const parser = new DOMParser(); // establish the parser\r\n const xmlDoc = parser.parseFromString(formxml, \"application/xml\"); // parse the XML\r\n /**\r\n * Then we can get the attributes we want from the parsed XML\r\n */\r\n const controls = processElements(xmlDoc.getElementsByTagName(\"control\")); // get control elements (will represent columns in the form)\r\n const sections = processElements(xmlDoc.getElementsByTagName(\"section\")); // self explanatory\r\n const tabs = processElements(xmlDoc.getElementsByTagName(\"tab\")); // self explanatory\r\n\r\n // Resolve all promises, filtering out any null values\r\n const resolvedRefs = await Promise.all([...controls, ...sections, ...tabs]);\r\n /**\r\n * Then, finally, 'enhance' the array, adding custom methods and a custom 'getter'\r\n * which will allow us to access individual nodes using the syntax `array[\"logical_name\"]`\r\n */\r\n return enhanceArray(\r\n resolvedRefs.filter((ref): ref is PowerPagesElement => ref !== null)\r\n );\r\n /** handle errors */\r\n } catch (error: unknown) {\r\n if (error instanceof Error) {\r\n console.error(error.message);\r\n throw error; // Re-throw the original error to keep stack trace\r\n } else {\r\n console.error(error);\r\n throw new Error(String(error)); // Ensure non-Error values are converted to a string\r\n }\r\n }\r\n}\r\n\r\nfunction processElements(element: HTMLCollectionOf<Element>) {\r\n return Array.from(element)\r\n .map((element) => {\r\n // use a helper function to determine the attribute we want based on the tagname of the element\r\n const identifyingAttribute = getIdentifyingAttribute(element.tagName);\r\n const datafieldname = element.getAttribute(identifyingAttribute);\r\n // if we don't find the desired thing,\r\n if (!datafieldname) return null;\r\n\r\n const referenceString: string | null = createReferenceString(\r\n element.tagName,\r\n datafieldname\r\n );\r\n if (!referenceString) return null;\r\n\r\n return get(referenceString).catch((error) => {\r\n console.warn(\r\n `Failed to create a reference to the form field: ${datafieldname}`,\r\n error\r\n );\r\n return null;\r\n });\r\n })\r\n .filter(Boolean); // Remove null values\r\n}\r\n\r\nfunction getIdentifyingAttribute(tagName: string): string {\r\n return tagName === \"control\"\r\n ? \"id\"\r\n : tagName === \"tab\" || tagName === \"section\"\r\n ? \"name\"\r\n : \"id\";\r\n}\r\n\r\nfunction createReferenceString(\r\n tagName: string,\r\n datafieldname: string\r\n): string | null {\r\n if (tagName === \"control\") return `#${datafieldname}`;\r\n if (tagName === \"tab\" || tagName === \"section\") {\r\n return `[data-name=\"${datafieldname}\"]`;\r\n }\r\n return null; // Explicitly return null instead of undefined\r\n}\r\n", "/**\r\n * @class LoadingSpinner - instantiate a spinner to handle loading state in your powerpages site\r\n */\r\n/********/ /********/ export default class LoadingSpinner extends HTMLElement {\r\n private element!: HTMLDivElement;\r\n constructor() {\r\n if (!document) {\r\n throw new Error(`Cannot instantiate 'LoadingSpinner': No DOM Found`);\r\n }\r\n super();\r\n this.id = \"loader\";\r\n this.classList.add(\"loader-overlay\", \"hidden\");\r\n\r\n this.element = document.createElement(\"div\");\r\n this.element.classList.add(\"spinner-border\", \"text-light\");\r\n this.element.role = \"status\";\r\n this.appendChild(this.element);\r\n\r\n const span: HTMLSpanElement = document.createElement(\"span\");\r\n span.classList.add(\"visually-hidden\");\r\n span.textContent = \"Loading...\";\r\n this.element.appendChild(span);\r\n\r\n // finally add this to the DOM\r\n document.body.appendChild(this);\r\n }\r\n\r\n /**\r\n * @method hide - Hides the loading spinner\r\n */\r\n public hide(): void {\r\n this.classList.add(\"hidden\");\r\n }\r\n\r\n /**\r\n * @method show - Shows the loading spinner\r\n */\r\n public show(): void {\r\n this.classList.remove(\"hidden\");\r\n }\r\n}\r\n\r\nconst uid: string = `loading-${crypto.randomUUID()}`;\r\ncustomElements.define(uid, LoadingSpinner);\r\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["// @ts-nocheck\r\n// Assume these globals are available in the PowerPages runtime:\r\ndeclare const shell: {\r\n getTokenDeferred(): JQuery.Promise<string>;\r\n};\r\n\r\ndeclare function validateLoginSession<T>(\r\n data: T,\r\n textStatus: string,\r\n jqXHR: JQuery.jqXHR,\r\n resolve: (value?: T | JQuery.Promise<T>) => void\r\n): void;\r\n\r\n/**\r\n * Custom HTTP wrapper function that handles authentication for the call from within PowerPages for you, making it all the easier to make API calls with {@link API}\r\n */\r\nexport default function safeAjax<T = any>(options: JQuery.AjaxSettings) {\r\n const deferredAjax = $.Deferred<T>();\r\n\r\n // shell is only available via runtime in a PowerPages portal\r\n\r\n shell\r\n .getTokenDeferred()\r\n .done(function (token) {\r\n // add headers for AJAX\r\n if (!options.headers) {\r\n $.extend(options, {\r\n headers: {\r\n __RequestVerificationToken: token,\r\n },\r\n });\r\n } else {\r\n options.headers[\"__RequestVerificationToken\"] = token;\r\n }\r\n $.ajax(options)\r\n .done(function (data: any, textStatus: string, jqXHR: any) {\r\n //eslint-disable-next-line\r\n validateLoginSession(data, textStatus, jqXHR, deferredAjax.resolve);\r\n })\r\n .fail(deferredAjax.reject); //AJAX\r\n })\r\n .fail(function () {\r\n deferredAjax.rejectWith(this, arguments); // on token failure pass the token AJAX and args\r\n });\r\n\r\n return deferredAjax.promise();\r\n}\r\n", "//@ts-nocheck\r\nimport safeAjax from \"../utils/safeAjax.ts\";\r\n\r\ninterface ODataJSON extends object {\r\n [key: `${string}@odata.bind` | string]: any;\r\n}\r\n\r\n/**\r\n * Provides abstract class `API` that allows basic create, read, and update operations in DataVerse via the PowerPages API\r\n * @method `createRecord` - Create a record in DataVerse\r\n * @method `getRecord<T>` - Get a record by ID from DataVerse\r\n * @method `getMultiple` - Get multiple records from DataVerse; with optional OData filtering\r\n * @method `updateRecord` - Update a record by ID in DataVerse\r\n */\r\nabstract class API {\r\n /**\r\n * @param tableSetName The dataverse set name for the table that you are updating a record in\r\n * @param data The JSON of the fields and data that are to be updated on the targeted record\r\n * @returns a Promise resolving the successful results *[record id]* of the POST request, or rejecting the failed results *[error]* of the POST request.\r\n */\r\n static createRecord(tableSetName: string, data: ODataJSON): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n safeAjax({\r\n type: \"POST\",\r\n url: `/_api/${tableSetName}`,\r\n data: JSON.stringify(data),\r\n contentType: \"application/json\",\r\n success: function (_response, _status, xhr) {\r\n resolve(xhr.getResponseHeader(\"entityid\"));\r\n },\r\n error: (error) => {\r\n reject(error);\r\n },\r\n });\r\n });\r\n }\r\n /**\r\n *\r\n * @param tableSetName The DataVerse SET name of the table being queried\r\n * @param recordID the GUID of the records to be retrieved\r\n * @param ODataQueryString *OPTIONAL* if desired, enter your own custom OData query for advanced GET results. e.g.: ?$select=column1,column2,column3\r\n * @returns a Promise resolving the successful results of the GET request, or rejecting the failed results of the GET request\r\n */\r\n static getRecord<T>(\r\n tableSetName: string,\r\n recordID: string,\r\n ODataQueryString?: string\r\n ): Promise<T> {\r\n return new Promise((resolve, reject) => {\r\n const url = `/_api/${tableSetName}(${recordID})${\r\n ODataQueryString ? `${ODataQueryString}` : \"\"\r\n }`;\r\n\r\n safeAjax({\r\n type: \"GET\",\r\n url: url,\r\n success: resolve,\r\n error: reject,\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * More flexible method for building completely custom queries\r\n */\r\n static request<T>(\r\n query: string,\r\n options?: JQuery.AjaxSettings\r\n ): Promise<T | Error> {\r\n return new Promise((success, error) => {\r\n const url = `/_api/${query}`;\r\n safeAjax({\r\n url,\r\n success,\r\n error,\r\n ...options,\r\n });\r\n });\r\n }\r\n /**\r\n *\r\n * @param tableSetName The dataverse set name of the table being queried\r\n * @param queryParameters *OPTIONAL* the OData query parameters for refining search results: *format = $filter=filters&$select=columns*\r\n * @returns a Promise resolving the successful results of the GET request, or rejecting the failed results of the GET request\r\n */\r\n static getMultiple<T = object>(\r\n tableSetName: string,\r\n queryParameters?: string\r\n ): Promise<Array<T>> {\r\n return new Promise((resolve, reject) => {\r\n // Construct the URL based on the presence of query parameters\r\n const url = `/_api/${tableSetName}${\r\n queryParameters ? `?${queryParameters}` : \"\"\r\n }`;\r\n\r\n safeAjax({\r\n type: \"GET\",\r\n url: url,\r\n success: function (response) {\r\n resolve(response.value);\r\n },\r\n error: reject,\r\n });\r\n });\r\n }\r\n\r\n /**\r\n *\r\n * @param tableSetName The dataverse set name for the table that you are updating a record in\r\n * @param recordId The GUID of the record that is being updated\r\n * @param data The JSON of the fields and data that are to be updated on the targeted record\r\n * @returns A Promise with the results of the API execution\r\n */\r\n static updateRecord(\r\n tableSetName: string,\r\n recordId: string,\r\n data: ODataJSON\r\n ): Promise<any> {\r\n return new Promise((resolve, reject) => {\r\n const url = `/_api/${tableSetName}(${recordId})`;\r\n\r\n safeAjax({\r\n type: \"PATCH\",\r\n url: url,\r\n data: JSON.stringify(data),\r\n success: resolve,\r\n error: reject,\r\n });\r\n });\r\n }\r\n}\r\n\r\nexport default API;\r\n", "export default class VisibilityManager {\r\n private declare visibilityController: HTMLElement | null;\r\n private defaultVisibility: string | null;\r\n\r\n public set defaultDisplay(newValue: string | null) {\r\n this.defaultVisibility = newValue;\r\n }\r\n\r\n constructor(target: HTMLElement) {\r\n // Set the default visibility controller to the element itself\r\n this.visibilityController = target;\r\n\r\n // If the element is a table, use its closest fieldset as the controller\r\n if (target.tagName === \"TABLE\") {\r\n const fieldset = target.closest(\"fieldset\");\r\n if (fieldset) {\r\n this.visibilityController = fieldset;\r\n }\r\n }\r\n\r\n // For specific tag types, use the closest 'td' if available as the controller\r\n const tagsRequiringTdParent = [\r\n \"SPAN\",\r\n \"INPUT\",\r\n \"TEXTAREA\",\r\n \"SELECT\",\r\n \"TABLE\",\r\n ];\r\n if (tagsRequiringTdParent.includes(target.tagName)) {\r\n const tdParent = target.closest(\"td\");\r\n if (tdParent) {\r\n this.visibilityController = tdParent;\r\n }\r\n }\r\n\r\n this.defaultVisibility = this.visibilityController.style.display;\r\n }\r\n\r\n public hide(): void {\r\n this.visibilityController!.style.display = \"none\";\r\n }\r\n\r\n public show(): void {\r\n this.visibilityController!.style.display = this.defaultVisibility!;\r\n }\r\n\r\n public toggleVisibility(shouldShow: boolean): void {\r\n shouldShow ? this.show() : this.hide();\r\n }\r\n\r\n public getVisibility(): true | false {\r\n return (\r\n window.getComputedStyle(this.visibilityController!).display !== \"none\" &&\r\n window.getComputedStyle(this.visibilityController!).visibility !==\r\n \"hidden\" &&\r\n this.visibilityController!.getBoundingClientRect().height > 0 &&\r\n this.visibilityController!.getBoundingClientRect().width > 0\r\n );\r\n }\r\n\r\n public destroy(): void {\r\n this.visibilityController = null;\r\n this.defaultVisibility = null;\r\n }\r\n}\r\n", "/**\r\n * For use in setting up event management in the instances of PowerPagesElement\r\n * @see {@link PowerPagesElement}\r\n */\r\nexport const EventTypes = {\r\n CHECKBOX: \"click\",\r\n RADIO: \"click\",\r\n SELECT: \"change\",\r\n TEXT: \"keyup\",\r\n DEFAULT: \"input\",\r\n} as const;\r\n", "export const init: symbol = Symbol(\"init\");\r\nexport const destroy: symbol = Symbol(\"destroy\");\r\n", "/**\r\n *\r\n * @param {string} titleString The text to display in the tooltip flyout content\r\n * @param iconStyle Optional CSS styles to apply to the info icon\r\n * @returns\r\n */\r\n/********/ /********/ export default class InfoElement extends HTMLElement {\r\n private flyoutContent: HTMLDivElement;\r\n private icon: HTMLElement;\r\n private observers: MutationObserver[] = [];\r\n\r\n /********/ constructor(\r\n titleString: string,\r\n iconStyle?: Partial<CSSStyleDeclaration>\r\n ) {\r\n super();\r\n // Input validation remains the same\r\n if (typeof titleString !== \"string\") {\r\n throw new Error(\r\n `argument \"titleString\" must be of type \"string\". Received: \"${typeof titleString}\"`\r\n );\r\n }\r\n if (iconStyle && typeof iconStyle !== \"object\") {\r\n throw new Error(\r\n `argument \"iconStyle\" must be of type \"object\". Received: \"${typeof iconStyle}\"`\r\n );\r\n }\r\n\r\n this.classList.add(\"info-icon\");\r\n\r\n this.icon = document.createElement(\"i\");\r\n this.icon.classList.add(\"fa\", \"fa-solid\", \"fa-info-circle\");\r\n this.icon.setAttribute(\"aria-label\", \"Info\");\r\n this.icon.style.cursor = \"pointer\";\r\n\r\n this.flyoutContent = document.createElement(\"div\");\r\n this.flyoutContent.innerHTML = titleString;\r\n this.flyoutContent.classList.add(\"flyout-content\");\r\n\r\n this.appendChild(this.icon);\r\n this.appendChild(this.flyoutContent);\r\n\r\n if (iconStyle) {\r\n Object.assign(this.icon.style, iconStyle);\r\n }\r\n\r\n this.handleClick = this.handleClick.bind(this);\r\n this.handleResize = this.handleResize.bind(this);\r\n this.handleTouchStart = this.handleTouchStart.bind(this);\r\n this.handleMouseEnter = this.handleMouseEnter.bind(this);\r\n this.handleMouseLeave = this.handleMouseLeave.bind(this);\r\n this.handleScroll = this.handleScroll.bind(this);\r\n\r\n this.flyoutContent.style.minWidth = this.getDesiredWidth();\r\n\r\n this.flyoutContent.style.display = \"none\";\r\n\r\n this.attachEventListeners();\r\n this.setupObservers();\r\n }\r\n\r\n /********/ private attachEventListeners(): void {\r\n document.body.addEventListener(\"click\", this.handleClick);\r\n self.addEventListener(\"resize\", this.handleResize);\r\n this.icon.addEventListener(\"touchstart\", this.handleTouchStart);\r\n this.addEventListener(\"mouseenter\", this.handleMouseEnter);\r\n this.addEventListener(\"mouseleave\", this.handleMouseLeave);\r\n self.addEventListener(\"scroll\", this.handleScroll);\r\n }\r\n\r\n /********/ private setupObservers(): void {\r\n // observe if element is removed, so that we can perform cleanup\r\n const _destroy_observer = new MutationObserver((mutations) => {\r\n for (const mut of mutations) {\r\n for (const node of Array.from(mut.removedNodes)) {\r\n if (node === this) {\r\n this.destroy();\r\n return;\r\n }\r\n }\r\n }\r\n });\r\n _destroy_observer.observe(document, {\r\n childList: true,\r\n subtree: true,\r\n attributes: false,\r\n });\r\n\r\n // observe for changes in the DOM, and trigger position\r\n const _position_observer = new MutationObserver(\r\n () => this.updateFlyoutWidth\r\n );\r\n _position_observer.observe(document, {\r\n childList: true,\r\n subtree: true,\r\n attributes: false,\r\n });\r\n\r\n // track observers for cleanup\r\n this.observers.push(_destroy_observer, _position_observer);\r\n }\r\n\r\n /********/ private getDesiredWidth(): string {\r\n // Get a reasonable width that works for center positioning\r\n const viewportWidth = self.innerWidth;\r\n const maxWidth = Math.min(viewportWidth - 40, 600); // Max 600px wide with 20px padding on each side\r\n return `${maxWidth}px`;\r\n }\r\n\r\n /********/ private positionFlyout(): void {\r\n // Always position the flyout in the center of the screen\r\n this.flyoutContent.style.display = \"block\";\r\n // Get the icon's position relative to the viewport\r\n const iconRect = this.icon.getBoundingClientRect();\r\n const flyoutRect = this.flyoutContent.getBoundingClientRect();\r\n const viewportHeight = self.innerHeight;\r\n const margin = 5; // Space between icon and flyout\r\n let topPosition = iconRect.bottom - margin; // Default below the icon\r\n // If the flyout would go beyond the viewport, position it above\r\n if (topPosition + flyoutRect.height > viewportHeight) {\r\n topPosition = iconRect.top - flyoutRect.height; // Move above the icon\r\n }\r\n // Apply positions\r\n this.flyoutContent.style.top = `${topPosition}px`;\r\n\r\n // then, adjust centeredness based on layout of page\r\n }\r\n\r\n /********/ private updateFlyoutWidth(): void {\r\n this.flyoutContent.style.minWidth = this.getDesiredWidth();\r\n }\r\n\r\n /********/ private handleClick(e: Event): void {\r\n if (!this.contains(e.target as Node)) {\r\n this.flyoutContent.style.display = \"none\";\r\n }\r\n }\r\n\r\n /********/ private handleResize(_e: Event): void {\r\n this.flyoutContent.style.minWidth = this.getDesiredWidth();\r\n }\r\n\r\n /********/ private handleTouchStart(): void {\r\n this.flyoutContent.style.display =\r\n this.flyoutContent.style.display === \"block\" ? \"none\" : \"block\";\r\n if (this.flyoutContent.style.display === \"block\") {\r\n this.positionFlyout();\r\n }\r\n }\r\n\r\n /********/ private handleMouseEnter(_e: MouseEvent): void {\r\n this.positionFlyout();\r\n }\r\n\r\n /********/ private handleMouseLeave(event: MouseEvent): void {\r\n // Check if we're not moving to a child element\r\n const relatedTarget = event.relatedTarget as Node;\r\n if (!this.contains(relatedTarget)) {\r\n this.flyoutContent.style.display = \"none\";\r\n }\r\n }\r\n\r\n /********/ private handleScroll(): void {\r\n const previousFlyoutDisplay = this.flyoutContent.style.display;\r\n if (previousFlyoutDisplay === \"none\") return;\r\n\r\n this.positionFlyout();\r\n\r\n this.flyoutContent.style.display = previousFlyoutDisplay;\r\n }\r\n\r\n /********/ private destroy(): void {\r\n document.body.removeEventListener(\"click\", this.handleClick);\r\n self.removeEventListener(\"resize\", this.handleResize);\r\n this.icon.removeEventListener(\"touchstart\", this.handleTouchStart);\r\n this.removeEventListener(\"mouseenter\", this.handleMouseEnter);\r\n this.removeEventListener(\"mouseleave\", this.handleMouseLeave);\r\n self.removeEventListener(\"scroll\", this.handleScroll);\r\n\r\n this.observers.forEach((obv) => obv.disconnect());\r\n }\r\n}\r\nconst uid: string = `info-icon-${crypto.randomUUID()}`;\r\ncustomElements.define(uid, InfoElement);\r\n", "/**\r\n * Provides an async way to capture DOM elements; for when querySelector cannot capture the target due to async DOM content loading\r\n * @param **target** - basic querySelector syntax to select an element\r\n * @param **root** - optional parameter to replace document as the root from which to perform the node search\r\n * @returns the element(s) targeted by the `querySelector` string\r\n */\r\nexport default function waitFor(\r\n target: string,\r\n root: Element | Document,\r\n multiple: false,\r\n debounceTime: number\r\n): Promise<HTMLElement>;\r\n\r\nexport default function waitFor(\r\n target: string,\r\n root: Element | Document,\r\n multiple: true,\r\n debounceTime: number\r\n): Promise<HTMLElement[]>;\r\n\r\nexport default function waitFor(\r\n target: string,\r\n root: Element | Document = document,\r\n multiple: boolean = false,\r\n debounceTime: number\r\n): Promise<HTMLElement | HTMLElement[]> {\r\n //\r\n return new Promise((resolve, reject) => {\r\n //\r\n if (multiple) {\r\n //\r\n let timeout: any;\r\n const observedElements: HTMLElement[] = [];\r\n const observedSet: Set<HTMLElement> = new Set();\r\n\r\n if (debounceTime < 1) {\r\n return resolve(\r\n <HTMLElement[]>Array.from(root.querySelectorAll(<string>target))\r\n );\r\n }\r\n const observer = new MutationObserver(() => {\r\n const found = <HTMLElement[]>(\r\n Array.from(root.querySelectorAll(<string>target))\r\n );\r\n\r\n // If elements are found, store them in observedElements\r\n found.forEach((element) => {\r\n if (!observedSet.has(element)) {\r\n observedSet.add(element);\r\n observedElements.push(element);\r\n }\r\n });\r\n\r\n // Clear the previous timeout and set a new one\r\n clearTimeout(timeout);\r\n timeout = setTimeout(() => {\r\n // Resolve the promise after debounce period if no more mutations\r\n if (observedElements.length > 0) {\r\n observer.disconnect();\r\n resolve(observedElements);\r\n } else {\r\n reject(\r\n new Error(\r\n `No elements found with target: \"${target}\" within ${\r\n debounceTime / 1000\r\n } seconds. If the element you are expecting has not loaded yet, consider raising your timeout.`\r\n )\r\n );\r\n }\r\n }, debounceTime);\r\n });\r\n\r\n observer.observe(root, {\r\n childList: true,\r\n subtree: true,\r\n attributes: false,\r\n });\r\n //\r\n } else {\r\n // Create observer to watch for target in DOM\r\n const observer = new MutationObserver(() => {\r\n const observedElement = <HTMLElement>root.querySelector(<string>target);\r\n if (observedElement) {\r\n clearTimeout(timeout);\r\n observer.disconnect();\r\n resolve(observedElement);\r\n }\r\n });\r\n const timeout = setTimeout(() => {\r\n observer.disconnect();\r\n reject(\r\n new Error(\r\n `Element not found by target: \"${target}\" within ${\r\n debounceTime / 1000\r\n } second. If the element you are expecting has not loaded yet, consider raising your timeout.`\r\n )\r\n );\r\n }, debounceTime);\r\n\r\n const element = <HTMLElement>root.querySelector(<string>target);\r\n if (element) {\r\n clearTimeout(timeout);\r\n return resolve(element);\r\n }\r\n\r\n observer.observe(root, {\r\n subtree: true,\r\n attributes: true,\r\n childList: true, // Detects added/removed child elements\r\n });\r\n //\r\n }\r\n //\r\n });\r\n //\r\n}\r\n", "import type DOMNodeReference from \"../ancillary/DOMNodeReference.ts\";\r\n\r\nclass CustomError extends Error {\r\n public node: DOMNodeReference;\r\n constructor(node: DOMNodeReference, message: string) {\r\n super(message);\r\n\r\n this.node = node;\r\n\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, this.constructor);\r\n }\r\n }\r\n}\r\n\r\nclass InitializationError extends CustomError {\r\n constructor(node: DOMNodeReference, error: string) {\r\n super(\r\n node,\r\n `There was an error initializing a DOMNodeReference for target: ${node.target}, :: ${error}`\r\n );\r\n }\r\n}\r\n\r\nclass NodeNotFoundError extends CustomError {\r\n constructor(node: DOMNodeReference) {\r\n super(node, `The targeted DOM element was not found: ${node.target}`);\r\n }\r\n}\r\n\r\nclass Page_ValidatorsNotFoundError extends CustomError {\r\n constructor(node: DOMNodeReference) {\r\n super(node, \"Page_Validators could not be found\");\r\n }\r\n}\r\n\r\nclass BusinessRuleError extends CustomError {\r\n constructor(node: DOMNodeReference) {\r\n super(node, `Error applying business rule to target: ${node.target}`);\r\n }\r\n}\r\n\r\nclass SelfReferenceError extends CustomError {\r\n constructor(node: DOMNodeReference) {\r\n super(\r\n node,\r\n \"Self-referential dependency found. A DOMNodeReference cannot depend on itself\"\r\n );\r\n }\r\n}\r\n\r\nclass LabelNotFoundError extends CustomError {\r\n constructor(node: DOMNodeReference) {\r\n super(node, `No label could be found for the target: ${node.target}`);\r\n }\r\n}\r\n\r\nclass IncorrectParameterError extends CustomError {\r\n constructor(\r\n node: DOMNodeReference,\r\n functionName: string,\r\n argName: string,\r\n expectedTypes: string[],\r\n receivedType: any\r\n ) {\r\n const concatTypes = expectedTypes.join(\" or \");\r\n\r\n super(\r\n node,\r\n `${functionName} expects ${argName} to be of type ${concatTypes}. Received: ${\r\n receivedType === null ? \"null\" : typeof receivedType\r\n }`\r\n );\r\n }\r\n}\r\n\r\nconst Errors = {\r\n NodeNotFoundError,\r\n InitializationError,\r\n Page_ValidatorsNotFoundError,\r\n BusinessRuleError,\r\n SelfReferenceError,\r\n LabelNotFoundError,\r\n IncorrectParameterError,\r\n};\r\n\r\nexport default Errors;\r\n", "import type EventManager from \"../ancillary/EventManager.ts\";\r\nimport type ValueManager from \"../ancillary/ValueManager.ts\";\r\nimport type VisibilityManager from \"./VisibilityManager.ts\";\r\nimport { EventTypes } from \"../constants/EventTypes.ts\";\r\nimport { init, destroy } from \"../constants/symbols.ts\";\r\nimport InfoElement from \"./InfoElement.ts\";\r\nimport waitFor from \"../core/waitFor.ts\";\r\nimport Errors from \"../errors/errors.ts\";\r\nimport DOMPurify from \"DOMPurify\";\r\n\r\nexport default abstract class DOMNodeReference {\r\n // declare static properties\r\n static instances: DOMNodeReference[] = [];\r\n\r\n // allow for indexing methods with symbols\r\n [key: symbol]: (...arg: any[]) => any;\r\n\r\n // properties initialized in the constructor\r\n public target: Element | string;\r\n public logicalName?: string;\r\n public root: Element;\r\n protected timeoutMs: number;\r\n protected isLoaded: boolean;\r\n\r\n /**\r\n * The value of the element that this node represents\r\n * stays in syncs with the live DOM elements?.,m via event handler\r\n */\r\n public get value() {\r\n return this.valueManager!.value;\r\n }\r\n\r\n public set value(newValue) {\r\n this.valueManager!.setValue(newValue);\r\n }\r\n\r\n public get checked() {\r\n return this.valueManager!.checked;\r\n }\r\n\r\n public set defaultDisplay(newValue: string | null) {\r\n this.visibilityManager!.defaultDisplay = newValue;\r\n }\r\n\r\n /**\r\n * The element targeted when instantiating DOMNodeReference.\r\n * Made available in order to perform normal DOM traversal,\r\n * or access properties not available through this class.\r\n */\r\n public declare element: HTMLElement;\r\n public visibilityManager!: VisibilityManager | null;\r\n public valueManager!: ValueManager | null;\r\n public eventManager!: EventManager | null;\r\n\r\n /**\r\n * Creates an instance of DOMNodeReference.\r\n * @param target - The CSS selector to find the desired DOM element.\r\n * @param root - Optionally specify the element within to search for the element targeted by 'target'\r\n * Defaults to 'document.body'\r\n */\r\n /******/ /******/ constructor(\r\n target: Element | string,\r\n root: Element = document.body,\r\n timeoutMs: number\r\n ) {\r\n this.target = target;\r\n this.logicalName = this._extractLogicalName(target);\r\n this.root = root;\r\n this.timeoutMs = timeoutMs;\r\n this.isLoaded = false;\r\n\r\n // The rest of initialization.\r\n }\r\n\r\n protected async [init](): Promise<void> {\r\n if (this.target instanceof HTMLElement) {\r\n this.element = this.target;\r\n } else {\r\n this.element = (await waitFor(\r\n this.target as string,\r\n this.root,\r\n false,\r\n this.timeoutMs\r\n )) as HTMLElement;\r\n }\r\n\r\n if (!this.element) {\r\n throw new Errors.NodeNotFoundError(this);\r\n }\r\n }\r\n\r\n // force extensions of this class to implement these methods\r\n protected abstract initValueManager(): void;\r\n protected abstract initVisibilityManager(): void;\r\n protected abstract initEventManager(): void;\r\n\r\n protected _extractLogicalName(target: Element | string): string {\r\n if (typeof target !== \"string\") return \"\";\r\n\r\n const bracketMatch = target.match(/\\[([^\\]]+)\\]/);\r\n if (!bracketMatch) return target.replace(/[#\\[\\]]/g, \"\");\r\n\r\n const content = bracketMatch[1];\r\n const quoteMatch = content.match(/[\"']([^\"']+)[\"']/);\r\n return (quoteMatch?.[1] || content).replace(/[#\\[\\]]/g, \"\");\r\n }\r\n\r\n protected _valueSync(): void {\r\n if (!this._isValidFormElement(this.element)) return;\r\n\r\n this.updateValue();\r\n const eventType = this._determineEventType();\r\n this.eventManager!.registerDOMEventListener(\r\n this.element,\r\n eventType,\r\n this.updateValue.bind(this)\r\n );\r\n\r\n if (this._isDateInput()) {\r\n this._dateSync(this.element as HTMLInputElement);\r\n }\r\n }\r\n\r\n protected _determineEventType(): keyof GlobalEventHandlersEventMap {\r\n if (this.element instanceof HTMLSelectElement) return \"change\";\r\n if (this.element instanceof HTMLTextAreaElement) return \"keyup\";\r\n if (!(this.element instanceof HTMLInputElement)) return EventTypes.DEFAULT;\r\n\r\n return (\r\n EventTypes[this.element.type.toUpperCase() as keyof typeof EventTypes] ||\r\n EventTypes.DEFAULT\r\n );\r\n }\r\n\r\n protected _isDateInput(): boolean {\r\n return (\r\n this.element instanceof HTMLInputElement &&\r\n this.element.dataset.type === \"date\"\r\n );\r\n }\r\n\r\n protected _isValidFormElement(element: Element): element is FormElement {\r\n return (\r\n element instanceof HTMLInputElement ||\r\n element instanceof HTMLSelectElement ||\r\n element instanceof HTMLTextAreaElement ||\r\n element instanceof HTMLSpanElement ||\r\n element instanceof HTMLButtonElement ||\r\n element instanceof HTMLFieldSetElement\r\n );\r\n }\r\n\r\n protected async _dateSync(element: HTMLInputElement): Promise<void> {\r\n const parentElement = element.parentElement;\r\n if (!parentElement) {\r\n throw new DOMException(\"Date input must have a parent element\");\r\n }\r\n\r\n const dateNode = (await waitFor(\r\n \"[data-date-format]\",\r\n parentElement,\r\n false,\r\n 1500\r\n )) as HTMLElement;\r\n\r\n this.valueManager!.element = dateNode;\r\n\r\n this.eventManager!.registerDOMEventListener(\r\n dateNode,\r\n \"select\",\r\n this.updateValue.bind(this)\r\n );\r\n }\r\n\r\n protected _bindMethods() {\r\n const prototype = Object.getPrototypeOf(this);\r\n\r\n for (const key of Object.getOwnPropertyNames(prototype) as Array<\r\n keyof this\r\n >) {\r\n const value = this[key];\r\n\r\n // Ensure we're binding only functions and skip the constructor\r\n if (key !== \"constructor\" && typeof value === \"function\") {\r\n this[key] = value.bind(this);\r\n }\r\n }\r\n }\r\n\r\n protected [destroy](): void {\r\n // Clear other references\r\n this.isLoaded = false;\r\n this.value = null;\r\n\r\n this.eventManager!.destroy();\r\n this.eventManager = null;\r\n this.visibilityManager!.destroy();\r\n this.visibilityManager = null;\r\n this.valueManager!.destroy();\r\n this.valueManager = null;\r\n }\r\n\r\n /**\r\n * Updates the value and checked state based on element type\r\n * @public\r\n */\r\n public async updateValue(e?: Event): Promise<void> {\r\n if (e && !e.isTrusted) return;\r\n await this.valueManager!.updateValue(e);\r\n this.triggerDependentsHandlers();\r\n }\r\n\r\n protected triggerDependentsHandlers(): void {\r\n this.eventManager!.dispatchDependencyHandlers();\r\n }\r\n\r\n /**\r\n * Sets up an event listener based on the specified event type, executing the specified\r\n * event handler\r\n * @param eventType - The DOM event to watch for\r\n * @param eventHandler - The callback function that runs when the\r\n * specified event occurs.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public on<K extends keyof GlobalEventHandlersEventMap>(\r\n eventType: K,\r\n eventHandler: (\r\n this: DOMNodeReference,\r\n e: GlobalEventHandlersEventMap[K]\r\n ) => void\r\n ): DOMNodeReference {\r\n if (typeof eventHandler !== \"function\") {\r\n throw new Errors.IncorrectParameterError(\r\n this,\r\n \"on\",\r\n \"eventHandler\",\r\n [\"function\"],\r\n typeof eventHandler\r\n );\r\n }\r\n\r\n const handler = eventHandler as (this: DOMNodeReference, e: Event) => void;\r\n this.eventManager!.registerDOMEventListener(\r\n this.element,\r\n eventType,\r\n handler.bind(this)\r\n );\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Hides the element by setting its display style to \"none\".\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public hide(): DOMNodeReference {\r\n this.visibilityManager!.hide();\r\n return this;\r\n }\r\n\r\n /**\r\n * Shows the element by restoring its default display style.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public show(): DOMNodeReference {\r\n this.visibilityManager!.show();\r\n return this;\r\n }\r\n\r\n /**\r\n * @param shouldShow - Either a function that returns true or false,\r\n * or a natural boolean to determine the visibility of this\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public toggleVisibility(\r\n shouldShow: EvaluationFunction | boolean\r\n ): DOMNodeReference {\r\n const bool: boolean =\r\n shouldShow instanceof Function ? shouldShow.call(this) : shouldShow;\r\n\r\n this.visibilityManager!.toggleVisibility(bool);\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the value of the HTML element.\r\n * @param value - The value to set for the HTML element.\r\n * for parents of boolean radios, pass true or false as value, or\r\n * an expression returning a boolean\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public setValue(value: (() => any) | any): DOMNodeReference {\r\n if (value instanceof Function) {\r\n value = value();\r\n }\r\n this.valueManager!.setValue(value);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Disables the element so that users cannot input any data\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public disable(): DOMNodeReference {\r\n (this.element as HTMLInputElement).disabled = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Clears all values and states of the element.\r\n * Handles different input types appropriately, and can be called\r\n * on an element containing N child inputs to clear all\r\n */\r\n public clearValue(): void {\r\n this.valueManager!.clearValue();\r\n\r\n // Handle nested input elements in container elements\r\n if (this._getChildren()) {\r\n this.callAgainstChildrenInputs((child) => child.clearValue());\r\n }\r\n }\r\n\r\n protected _getChildren(): DOMNodeReference[] | null {\r\n const childInputs: Element[] = Array.from(\r\n this.element.querySelectorAll(\"input, select, textarea\")\r\n );\r\n const childIds: string[] = childInputs.map((input) => {\r\n return input.id;\r\n });\r\n\r\n const children = DOMNodeReference.instances.filter((ref) => {\r\n return childIds.includes(ref.element.id);\r\n });\r\n\r\n return children.length > 0 ? children : null;\r\n }\r\n\r\n protected callAgainstChildrenInputs(\r\n callback: (child: DOMNodeReference) => any\r\n ): void {\r\n // Handle nested input elements in container elements\r\n const children: DOMNodeReference[] | null = this._getChildren();\r\n if (!children) {\r\n console.error(\"No child inputs found for target: \", this);\r\n return;\r\n }\r\n\r\n for (const child of children) {\r\n callback(child);\r\n }\r\n }\r\n\r\n /**\r\n * Enables the element so that users can input data\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public enable(): DOMNodeReference {\r\n (this.element as HTMLInputElement).disabled = false;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param elements - The elements to prepend to the element targeted by this.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public prepend(...elements: HTMLElement[]): DOMNodeReference {\r\n this.element.prepend(...elements);\r\n return this;\r\n }\r\n\r\n /**\r\n * Appends child elements to the HTML element.\r\n * @param elements - The elements to append to the element targeted by this.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public append(...elements: HTMLElement[]): DOMNodeReference {\r\n this.element.append(...elements);\r\n return this;\r\n }\r\n\r\n /**\r\n * Inserts elements before the HTML element.\r\n * @param elements - The elements to insert before the HTML element.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public before(...elements: HTMLElement[]): DOMNodeReference {\r\n this.element.before(...elements);\r\n return this;\r\n }\r\n\r\n /**\r\n * Inserts elements after the HTML element.\r\n * @param elements - The elements to insert after the HTML element.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public after(...elements: HTMLElement[]): DOMNodeReference {\r\n this.element.after(...elements);\r\n return this;\r\n }\r\n\r\n /**\r\n * Retrieves the label associated with the HTML element.\r\n * @returns The label element associated with this element.\r\n */\r\n public getLabel(): HTMLElement | null {\r\n const label =\r\n (document.querySelector(`#${this.element.id}_label`) as HTMLElement) ||\r\n null;\r\n if (!label) throw new Errors.LabelNotFoundError(this);\r\n return label;\r\n }\r\n\r\n /**\r\n * Adds a tooltip with specified text to the label associated with the HTML element.\r\n * @param innerHTML - The innerHTML to append into the tooltip.\r\n * @param containerStyle - Optional object with CSS Styles to apply to the info element\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public addLabelTooltip(\r\n innerHTML: string,\r\n containerStyle?: Partial<CSSStyleDeclaration>\r\n ): DOMNodeReference {\r\n const safeHTML = DOMPurify.sanitize(innerHTML);\r\n this.getLabel()?.append(\r\n new InfoElement(safeHTML, containerStyle || undefined)\r\n );\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds a tooltip with the specified text to the element\r\n * @param innerHTML - The innerHTML to append into the tooltip\r\n * @param containerStyle - Optional object with CSS Styles to apply to the info element\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public addTooltip(\r\n innerHTML: string,\r\n containerStyle?: Partial<CSSStyleDeclaration>\r\n ): DOMNodeReference {\r\n const safeHTML = DOMPurify.sanitize(innerHTML);\r\n this.append(new InfoElement(safeHTML, containerStyle || undefined));\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the inner HTML content of the HTML element.\r\n * @param string - The text to set as the inner HTML of the element.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n set innerHTML(innerHTML: string) {\r\n const safeHTML = DOMPurify.sanitize(innerHTML);\r\n this.element.innerHTML = safeHTML;\r\n }\r\n\r\n /**\r\n * Removes this element from the DOM\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public remove() {\r\n this.element.remove();\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets inline CSS styles on the element.\r\n * @param options - An object containing CSS property-value pairs, e.g., { display: 'block' }.\r\n * @returns The instance, enabling method chaining.\r\n */\r\n public setStyle(options: Partial<CSSStyleDeclaration>): DOMNodeReference {\r\n if (options === null || typeof options !== \"object\") {\r\n throw new Errors.IncorrectParameterError(\r\n this,\r\n \"setStyle\",\r\n \"options\",\r\n [\"Partial<CSSStyleDeclaration>\"],\r\n typeof options\r\n );\r\n }\r\n\r\n // Iterate over own enumerable properties of the options object.\r\n Object.entries(options).forEach(([prop, value]) => {\r\n // Skip properties that are undefined.\r\n if (value !== undefined) {\r\n // Here we cast 'prop' as a key of CSSStyleDeclaration.\r\n // Using bracket notation allows dynamic property access.\r\n (this.element.style as any)[prop] = value;\r\n }\r\n });\r\n\r\n return this;\r\n }\r\n\r\n // #region Apply Business Rule\r\n /**\r\n * Applies a business rule to manage visibility, required state, value, and disabled state dynamically.\r\n * @see {@link BusinessRule}\r\n * @param rule The business rule containing conditions for various actions.\r\n * @param dependencies For re-evaluation of conditions when the state of the dependencies change\r\n * @returns Instance of this for method chaining.\r\n */\r\n public applyBusinessRule(\r\n rule: BusinessRule,\r\n dependencies: DependencyArray<DOMNodeReference>\r\n ): DOMNodeReference {\r\n try {\r\n // Create validator if needed (this is only needed once during setup)\r\n if (rule.setRequirements) {\r\n this._setupRequirementsValidator(rule.setRequirements());\r\n }\r\n\r\n // Apply the rules immediately\r\n const handler = this._createBusinessRuleHandler(rule);\r\n handler();\r\n\r\n // Setup dependency tracking\r\n if (dependencies.length) {\r\n this._configureDependencyTracking(handler, dependencies);\r\n }\r\n\r\n return this;\r\n } catch (error) {\r\n if (error instanceof Error) throw error;\r\n else throw new Errors.BusinessRuleError(this);\r\n }\r\n }\r\n // #region =========\r\n\r\n private _setupRequirementsValidator(\r\n requirements: FieldValidationRules\r\n ): void {\r\n const { isRequired, isValid } = requirements;\r\n\r\n if (typeof Page_Validators === \"undefined\") {\r\n throw new Errors.Page_ValidatorsNotFoundError(this);\r\n }\r\n\r\n let evaluationFunction = () => true;\r\n\r\n if (isRequired && isValid) {\r\n evaluationFunction = () => {\r\n const isFieldRequired = isRequired.call(this);\r\n const isFieldVisible = this.visibilityManager!.getVisibility();\r\n return (\r\n !isFieldRequired ||\r\n (isFieldVisible && isValid.call(this, isFieldRequired))\r\n );\r\n };\r\n } else if (isValid) {\r\n evaluationFunction = () => {\r\n const isFieldVisible = this.visibilityManager!.getVisibility();\r\n return isFieldVisible && isValid.call(this, false);\r\n };\r\n } else if (isRequired) {\r\n evaluationFunction = () => {\r\n const isFieldVisible = this.visibilityManager!.getVisibility();\r\n return isFieldVisible && isRequired.call(this);\r\n };\r\n }\r\n\r\n this._createValidator(evaluationFunction);\r\n }\r\n\r\n private _createBusinessRuleHandler(rule: BusinessRule): BusinessRuleHandler {\r\n return (): void => {\r\n let clearValues: boolean = false;\r\n\r\n // Handle visibility\r\n if (rule.setVisibility) {\r\n const visibilityCondition = rule.setVisibility;\r\n const isVisible = visibilityCondition.call(this);\r\n clearValues = !isVisible;\r\n this.toggleVisibility(isVisible);\r\n }\r\n\r\n // Handle requirements\r\n if (rule.setRequirements && rule.setRequirements().isRequired) {\r\n const { isRequired } = rule.setRequirements();\r\n this.setRequiredLevel(isRequired!.call(this));\r\n }\r\n\r\n // Handle value setting\r\n if (rule.setValue) {\r\n const { condition, value } = rule.setValue();\r\n if (condition.call(this)) {\r\n const finalValue = value instanceof Function ? value() : value;\r\n this.setValue.call(this, finalValue);\r\n }\r\n }\r\n\r\n // Handle disabled state\r\n if (rule.setDisabled) {\r\n const disabledCondition = rule.setDisabled;\r\n disabledCondition.call(this) ? this.disable() : this.enable();\r\n }\r\n\r\n // Clear values if needed\r\n if (clearValues && !rule.setValue) {\r\n this.clearValue();\r\n }\r\n\r\n this.triggerDependentsHandlers();\r\n };\r\n }\r\n\r\n private _createValidator(evaluationFunction: EvaluationFunction): void {\r\n const fieldDisplayName = (() => {\r\n let label: any = this.getLabel();\r\n if (!label) {\r\n throw new Errors.LabelNotFoundError(this);\r\n }\r\n label = label.innerHTML;\r\n if (label.length > 50) {\r\n label = label.substring(0, 50) + \"...\";\r\n }\r\n return label;\r\n })();\r\n\r\n const validatorId = `${this.element.id}Validator`;\r\n\r\n const newValidator = document.createElement(\"span\");\r\n newValidator.style.display = \"none\";\r\n newValidator.id = validatorId;\r\n\r\n Object.assign(newValidator, {\r\n controltovalidate: this.element.id,\r\n errormessage: `<a href='#${this.element.id}_label'>${fieldDisplayName} is a required field</a>`,\r\n evaluationfunction: evaluationFunction.bind(this),\r\n });\r\n\r\n if (Page_Validators == undefined)\r\n throw new Errors.Page_ValidatorsNotFoundError(this);\r\n\r\n Page_Validators.push(newValidator);\r\n }\r\n\r\n private _configureDependencyTracking(\r\n handler: DependencyHandler,\r\n dependencies: DOMNodeReference[]\r\n ): void {\r\n if (dependencies.length < 1) {\r\n console.error(\r\n `powerpagestoolkit: No dependencies specified for ${this.element.id}. ` +\r\n \"Include all required nodes in the dependency array for proper tracking.\"\r\n );\r\n return;\r\n }\r\n\r\n dependencies.forEach((dependency) => {\r\n if (!dependency || !(dependency instanceof DOMNodeReference)) {\r\n throw new TypeError(\r\n \"Each dependency must be a valid DOMNodeReference instance\"\r\n );\r\n }\r\n\r\n // Check for self-referential dependency\r\n if (dependency.logicalName === this.logicalName) {\r\n throw new Errors.SelfReferenceError(this);\r\n }\r\n\r\n // The node that THIS depends on needs to be able to send notifications to its dependents\r\n // dependency.dependents.set(this, handler.bind(this));\r\n dependency.eventManager!.registerDependent(this, handler.bind(this));\r\n });\r\n }\r\n\r\n /**\r\n * Sets the required level for the field by adding or removing the \"required-field\" class on the label.\r\n *\r\n * @param isRequired Determines whether the field should be marked as required.\r\n * If true, the \"required-field\" class is added to the label; if false, it is removed.\r\n * @returns Instance of this [provides option to method chain]\r\n */\r\n public setRequiredLevel(\r\n isRequired: EvaluationFunction | boolean\r\n ): DOMNodeReference {\r\n if (isRequired instanceof Function) {\r\n isRequired.call(this)\r\n ? this.getLabel()?.classList.add(\"required-field\")\r\n : this.getLabel()?.classList.remove(\"required-field\");\r\n return this;\r\n } else {\r\n isRequired\r\n ? this.getLabel()?.classList.add(\"required-field\")\r\n : this.getLabel()?.classList.remove(\"required-field\");\r\n return this;\r\n }\r\n }\r\n\r\n /**\r\n * Executes a callback function once the element is fully loaded.\r\n * If the element is already loaded, the callback is called immediately.\r\n * Otherwise, a MutationObserver is used to detect when the element is added to the DOM.\r\n * @param callback A callback function to execute once the element is loaded.\r\n * Receives instance of 'this' as an argument\r\n */\r\n public onceLoaded(callback: (instance: DOMNodeReference) => any): void {\r\n if (this.isLoaded) {\r\n callback(this);\r\n return;\r\n }\r\n\r\n if (this.target instanceof HTMLElement) {\r\n callback(this);\r\n return;\r\n }\r\n const observer = new MutationObserver(\r\n function (this: DOMNodeReference) {\r\n if (document.querySelector(this.target as string)) {\r\n observer.disconnect(); // Stop observing once loaded\r\n this.isLoaded = true;\r\n callback(this); // Call the provided callback\r\n }\r\n }.bind(this)\r\n );\r\n\r\n this.eventManager!.registerObserver(observer, {\r\n nodeToObserve: document.body,\r\n options: { subtree: true, childList: true },\r\n });\r\n }\r\n}\r\n", "/********/ /********/ export default abstract class InputMask {\r\n abstract input: HTMLInputElement;\r\n\r\n constructor() {}\r\n\r\n protected abstract setupEventListeners(): void;\r\n\r\n protected abstract formatInput(): void;\r\n\r\n protected onFocus(): void {\r\n // Select all text on focus for easier editing\r\n setTimeout(() => this.input.select(), 0);\r\n }\r\n\r\n protected onBlur(): void {\r\n // Ensure proper formatting when leaving the field\r\n this.formatInput();\r\n }\r\n\r\n // Set a new numerical value\r\n public setValue(value: any): void {\r\n this.input.value = String(value);\r\n }\r\n\r\n // Destroy the mask and remove event listeners\r\n public abstract destroy(): void;\r\n}\r\n", "import InputMask from \"./InputMask.ts\";\r\n\r\ntype CountryCodeFormat = \"+\" | \"()\" | \"00\";\r\n\r\ninterface PhoneNumberMaskOptions {\r\n countryCode?: string; // The actual country code (e.g., \"1\" for US)\r\n countryCodeFormat?: CountryCodeFormat; // How to format the country code\r\n format: string; // Format for the main phone number (e.g., \"(xxx) xxx-xxxx\")\r\n}\r\n\r\nexport default class PhoneNumberMask extends InputMask {\r\n public override input: HTMLInputElement;\r\n protected options: PhoneNumberMaskOptions;\r\n\r\n constructor(\r\n inputElement: HTMLInputElement,\r\n options: Partial<PhoneNumberMaskOptions> = {}\r\n ) {\r\n super();\r\n this.input = inputElement;\r\n this.options = {\r\n format: options.format || \"(xxx) xxx-xxxx\",\r\n countryCode: options.countryCode || \"\",\r\n countryCodeFormat: options.countryCodeFormat || \"+\",\r\n };\r\n\r\n this.onFocus = this.onFocus.bind(this);\r\n this.formatInput = this.formatInput.bind(this);\r\n this.onBlur = this.onBlur.bind(this);\r\n\r\n this.setupEventListeners();\r\n\r\n // Initial formatting\r\n setTimeout(() => {\r\n this.formatInput();\r\n }, 0);\r\n }\r\n\r\n protected override setupEventListeners(): void {\r\n // Add specific handlers for phone input if needed\r\n this.input.addEventListener(\"focus\", this.onFocus);\r\n this.input.addEventListener(\"input\", this.formatInput);\r\n this.input.addEventListener(\"blur\", this.onBlur);\r\n }\r\n\r\n protected formatInput(): void {\r\n const value = this.input.value;\r\n\r\n // Store caret position\r\n const caretPosition = this.input.selectionStart || 0;\r\n const oldLength = value.length;\r\n\r\n // Allow only digits and extract them\r\n const digits = value.replace(/\\D/g, \"\");\r\n\r\n // Format according to the specified format\r\n const formattedValue = this.formatPhoneNumber(digits);\r\n\r\n // Update the input value\r\n this.input.value = formattedValue;\r\n\r\n // Adjust caret position based on the change in length\r\n const newPosition = Math.min(\r\n caretPosition + (formattedValue.length - oldLength),\r\n formattedValue.length\r\n );\r\n this.input.setSelectionRange(newPosition, newPosition);\r\n }\r\n\r\n private formatPhoneNumber(digits: string): string {\r\n if (!digits) return \"\";\r\n\r\n let phoneDigits = digits;\r\n let countryCodeValue = \"\";\r\n\r\n // Extract country code digits if a country code is specified\r\n if (this.options.countryCode) {\r\n const countryCodeLength = this.options.countryCode.length;\r\n\r\n // If we have enough digits, use them for the country code\r\n if (digits.length > countryCodeLength) {\r\n countryCodeValue = digits.substring(0, countryCodeLength);\r\n phoneDigits = digits.substring(countryCodeLength);\r\n } else {\r\n // Not enough digits for both country code and phone, prioritize country code\r\n countryCodeValue = digits;\r\n phoneDigits = \"\";\r\n }\r\n }\r\n\r\n // Format country code according to the specified format\r\n let formattedCountryCode = \"\";\r\n if (countryCodeValue) {\r\n switch (this.options.countryCodeFormat) {\r\n case \"+\":\r\n formattedCountryCode = `+${countryCodeValue} `;\r\n break;\r\n case \"()\":\r\n formattedCountryCode = `(${countryCodeValue}) `;\r\n break;\r\n case \"00\":\r\n formattedCountryCode = `00${countryCodeValue} `;\r\n break;\r\n default:\r\n formattedCountryCode = `+${countryCodeValue} `;\r\n }\r\n }\r\n\r\n // Format the main phone number\r\n let result = this.options.format;\r\n let digitIndex = 0;\r\n\r\n // Replace each 'x' in the format with a digit from phoneDigits\r\n for (let i = 0; i < result.length && digitIndex < phoneDigits.length; i++) {\r\n if (result[i] === \"x\") {\r\n result =\r\n result.substring(0, i) +\r\n phoneDigits[digitIndex++] +\r\n result.substring(i + 1);\r\n }\r\n }\r\n\r\n // Remove any remaining 'x' placeholders\r\n result = result.replace(/x/g, \"\");\r\n\r\n // Trim any extra formatting at the end if not all digits are used\r\n const lastNonFormatChar = result.split(\"\").findIndex((char, index) => {\r\n return (\r\n !/\\d/.test(char) &&\r\n result.substring(index).indexOf(\"x\") === -1 &&\r\n result.substring(index).replace(/[\\s\\-()]/g, \"\").length === 0\r\n );\r\n });\r\n\r\n if (lastNonFormatChar !== -1) {\r\n result = result.substring(0, lastNonFormatChar);\r\n }\r\n\r\n return formattedCountryCode + result;\r\n }\r\n\r\n protected override onFocus(): void {\r\n // Select all text on focus for easier editing\r\n setTimeout(() => this.input.select(), 0);\r\n }\r\n\r\n protected override onBlur(): void {\r\n // Ensure proper formatting when leaving the field\r\n this.formatInput();\r\n\r\n // If the value has too few digits, consider clearing or keeping minimal format\r\n const digits = this.getDigits();\r\n const minLength = this.options.countryCode\r\n ? 7 + this.options.countryCode.length\r\n : 7; // Minimum reasonable length\r\n\r\n if (digits.length < minLength) {\r\n // Either clear completely or maintain basic format based on UX preference\r\n // this.input.value = \"\"; // Option 1: Clear completely\r\n // Option 2: Keep partial format with what digits we have (default)\r\n }\r\n }\r\n\r\n // Get the raw digits\r\n public getDigits(): string {\r\n return this.input.value.replace(/\\D/g, \"\");\r\n }\r\n\r\n // Get country code digits separately\r\n public getCountryCode(): string {\r\n if (!this.options.countryCode) return \"\";\r\n\r\n const digits = this.getDigits();\r\n const countryCodeLength = this.options.countryCode.length;\r\n\r\n return digits.length >= countryCodeLength\r\n ? digits.substring(0, countryCodeLength)\r\n : digits;\r\n }\r\n\r\n // Get phone number digits without country code\r\n public getPhoneDigits(): string {\r\n if (!this.options.countryCode) return this.getDigits();\r\n\r\n const digits = this.getDigits();\r\n const countryCodeLength = this.options.countryCode.length;\r\n\r\n return digits.length > countryCodeLength\r\n ? digits.substring(countryCodeLength)\r\n : \"\";\r\n }\r\n\r\n // Set a new phone number value (digits only)\r\n public override setValue(digits: string): void {\r\n // Ensure we only have digits\r\n const cleanDigits = digits.replace(/\\D/g, \"\");\r\n this.input.value = this.formatPhoneNumber(cleanDigits);\r\n }\r\n\r\n // Check if the phone number has a valid length\r\n public isValid(): boolean {\r\n const phoneDigits = this.getPhoneDigits();\r\n const countryDigits = this.getCountryCode();\r\n\r\n // Check if country code is complete\r\n const isCountryCodeValid =\r\n !this.options.countryCode ||\r\n countryDigits.length === this.options.countryCode.length;\r\n\r\n // Most phone numbers have 10 digits, but this can be adjusted\r\n return isCountryCodeValid && phoneDigits.length >= 10;\r\n }\r\n\r\n public destroy(): void {\r\n this.input.removeEventListener(\"focus\", this.onFocus);\r\n this.input.removeEventListener(\"input\", this.formatInput);\r\n this.input.removeEventListener(\"blur\", this.onBlur);\r\n }\r\n}\r\n", "import type DOMNodeReference from \"./DOMNodeReference.ts\";\r\n\r\ndeclare type EventType = string;\r\ndeclare type Handler = (this: DOMNodeReference, ...args: any[]) => void;\r\ndeclare type Listeners = Set<DOMNodeReference>;\r\n\r\n/********/ /********/ export default class EventManager {\r\n private readonly events: Map<EventType, Handler> = new Map();\r\n private readonly listeners: Map<EventType, Listeners> = new Map();\r\n private readonly dependencyHandlers: Set<[DOMNodeReference, Handler]> =\r\n new Set();\r\n private observers: Array<MutationObserver | ResizeObserver> = [];\r\n private boundListeners: Array<BoundEventListener> = [];\r\n\r\n constructor() {}\r\n\r\n /********/ public dispatchDependencyHandlers(): void {\r\n for (const [dependency, handler] of this.dependencyHandlers) {\r\n handler.call(dependency);\r\n }\r\n }\r\n\r\n /********/ public registerDependent(\r\n dependency: DOMNodeReference,\r\n handler: Handler\r\n ): \"success\" | Error {\r\n try {\r\n this.dependencyHandlers.add([dependency, handler]);\r\n return \"success\";\r\n } catch {\r\n return new Error(`Failed register dependant: ${dependency.target}`);\r\n }\r\n }\r\n\r\n /********/ public registerEvent(\r\n event: EventType,\r\n handler: Handler\r\n ): \"success\" | Error {\r\n if (this.events.has(event)) {\r\n console.error(\"Event registration has already been defined for: \", event);\r\n return new Error(\r\n `Event registration has already been defined for: ${event}`\r\n );\r\n }\r\n this.listeners.set(event, new Set());\r\n this.events.set(event, handler);\r\n return \"success\";\r\n }\r\n\r\n /********/ public registerListener(\r\n event: EventType,\r\n listener: DOMNodeReference\r\n ): \"success\" | Error {\r\n if (this.events.has(event)) {\r\n const listeners: Listeners = this.listeners.get(event) ?? new Set();\r\n listeners.add(listener);\r\n this.listeners.set(event, listeners);\r\n return \"success\";\r\n } else {\r\n console.error(\"No event registration found for: \", event);\r\n return new Error(`No event registration found for: ${event}`);\r\n }\r\n }\r\n\r\n /********/ public emit(eventType: EventType, ...args: any[]): void {\r\n if (this.events.has(eventType)) {\r\n //\r\n const event: Handler = this.events.get(eventType) as Handler;\r\n const listeners: Listeners | undefined = this.listeners.get(eventType);\r\n //\r\n if (!listeners) return;\r\n //\r\n for (const listener of listeners) {\r\n event.call(listener, ...args);\r\n }\r\n //\r\n } else {\r\n console.error(\"Event not found in EventRegistry: \", eventType);\r\n }\r\n return;\r\n }\r\n\r\n /********/ public stopListening(listener: DOMNodeReference): void {\r\n for (const [_event, listeners] of this.listeners) {\r\n if (listeners.has(listener)) listeners.delete(listener);\r\n }\r\n }\r\n\r\n /********/ public registerObserver(\r\n observer: MutationObserver | ResizeObserver,\r\n observerOptions: {\r\n nodeToObserve: Element;\r\n options: Partial<ResizeObserverOptions> | Partial<MutationObserverInit>;\r\n }\r\n ): void {\r\n const { nodeToObserve, options } = observerOptions;\r\n observer.observe(nodeToObserve, options);\r\n this.observers.push(observer);\r\n }\r\n\r\n /********/ public registerDOMEventListener(\r\n element: Element,\r\n eventType: keyof HTMLElementEventMap,\r\n handler: (e: Event) => unknown\r\n ): void {\r\n element.addEventListener(eventType, handler);\r\n\r\n this.boundListeners.push({\r\n element,\r\n handler,\r\n event: eventType,\r\n });\r\n }\r\n\r\n /********/ public destroy(): void {\r\n // Remove all bound event listeners\r\n this.boundListeners?.forEach((binding) => {\r\n binding.element?.removeEventListener(binding.event, binding.handler);\r\n });\r\n this.boundListeners = []; // Clear the array\r\n\r\n // Disconnect all observers\r\n this.observers?.forEach((observer) => {\r\n observer.disconnect();\r\n });\r\n this.observers = []; // Clear the array\r\n\r\n this.events.clear();\r\n\r\n this.dependencyHandlers.clear();\r\n\r\n this.listeners.clear();\r\n }\r\n}\r\n", "import { init, destroy } from \"../constants/symbols.ts\";\r\nimport VisibilityManager from \"./VisibilityManager.ts\";\r\nimport DOMNodeReference from \"./DOMNodeReference.ts\";\r\nimport EventManager from \"./EventManager.ts\";\r\nimport ValueManager from \"./ValueManager.ts\";\r\nimport Errors from \"../errors/errors.ts\";\r\n\r\nexport default class Radio extends DOMNodeReference {\r\n // allow for indexing methods with symbols\r\n [key: symbol]: (...arg: any[]) => any;\r\n\r\n public radioType: RadioType | undefined;\r\n public declare radioParent: DOMNodeReference | undefined;\r\n\r\n constructor(\r\n parent: DOMNodeReference,\r\n target: Element | string,\r\n root: Element = document.body,\r\n timeoutMs: number,\r\n radioType: RadioType\r\n ) {\r\n super(target, root, timeoutMs);\r\n\r\n this.radioParent = parent;\r\n this.radioType = radioType;\r\n }\r\n\r\n public async [init](): Promise<void> {\r\n /**\r\n * dynamically define the s.init method using our custom symbol\r\n * this makes it so that the s.init method cannot be accessed outside\r\n * of this package: i.e. by any consumers of the package\r\n */\r\n try {\r\n await super[init]();\r\n this.initEventManager();\r\n this.initVisibilityManager();\r\n this.initValueManager();\r\n\r\n // we want to ensure that all method calls from the consumer have access to 'this'\r\n this._bindMethods();\r\n\r\n // when the element is removed from the DOM, destroy this\r\n const observer = new MutationObserver((mutations) => {\r\n for (const mutation of mutations) {\r\n if (Array.from(mutation.removedNodes).includes(this.element)) {\r\n this[destroy]();\r\n observer.disconnect();\r\n break;\r\n }\r\n }\r\n });\r\n\r\n observer.observe(document.body, {\r\n childList: true,\r\n subtree: true,\r\n });\r\n\r\n DOMNodeReference.instances.push(this);\r\n\r\n this.isLoaded = true;\r\n } catch (error) {\r\n const errorMessage: string =\r\n error instanceof Error ? error.message : String(error);\r\n throw new Errors.InitializationError(this, errorMessage);\r\n }\r\n }\r\n\r\n protected override initEventManager(): void {\r\n this.eventManager = new EventManager();\r\n }\r\n\r\n protected override initValueManager(): void {\r\n this.valueManager = new ValueManager(this);\r\n\r\n this._valueSync();\r\n }\r\n\r\n protected override initVisibilityManager(): void {\r\n this.visibilityManager = new VisibilityManager(this.element);\r\n }\r\n\r\n override [destroy](): void {\r\n super[destroy]();\r\n this.radioParent = undefined;\r\n this.radioType = undefined;\r\n }\r\n}\r\n", "import PowerPagesElement from \"../core/PowerPagesElement.ts\";\r\nimport type DOMNodeReference from \"./DOMNodeReference.ts\";\r\nimport Radio from \"./Radio.ts\";\r\n\r\nexport default class ValueManager {\r\n public value: any;\r\n public checked: true | false = false;\r\n public element: HTMLElement | null;\r\n private noRadio: Radio | undefined;\r\n private yesRadio: Radio | undefined;\r\n public radioParent?: DOMNodeReference | undefined;\r\n private isRadio: boolean = false;\r\n private radioType: RadioType | undefined;\r\n\r\n constructor(instance: DOMNodeReference) {\r\n if (instance instanceof PowerPagesElement) {\r\n this.noRadio = instance.noRadio;\r\n this.yesRadio = instance.yesRadio;\r\n this.radioParent = undefined;\r\n } else if (instance instanceof Radio) {\r\n this.isRadio = true;\r\n this.noRadio = undefined;\r\n this.yesRadio = undefined;\r\n this.radioParent = instance.radioParent;\r\n this.radioType = instance.radioType;\r\n }\r\n\r\n this.element = instance.element;\r\n }\r\n\r\n public setValue(value: any): void {\r\n const validatedValue = this._validateValue(value);\r\n\r\n if (this.yesRadio instanceof Radio && this.noRadio instanceof Radio) {\r\n (this.yesRadio.element as HTMLInputElement).checked = Boolean(value);\r\n (this.noRadio.element as HTMLInputElement).checked = Boolean(!value);\r\n this.value = value;\r\n (this.element as HTMLInputElement).checked = Boolean(value);\r\n (this.element as HTMLInputElement).value = value;\r\n } else if (\r\n this.isRadio ||\r\n (this.element as HTMLInputElement).type === \"radio\"\r\n ) {\r\n (this.element as HTMLInputElement).checked = value;\r\n this.checked = value;\r\n this.value = value;\r\n this.radioParent?.updateValue();\r\n } else {\r\n (this.element as HTMLInputElement).value = validatedValue;\r\n this.value = validatedValue;\r\n }\r\n }\r\n\r\n public async updateValue(e?: Event): Promise<void> {\r\n if (e) {\r\n e.stopPropagation();\r\n }\r\n\r\n const elementValue = await this.getElementValue();\r\n this.value = elementValue.value;\r\n\r\n if (elementValue.checked !== undefined) {\r\n this.checked = elementValue.checked;\r\n }\r\n\r\n // need a way to make sure radios stay in sync with each-other. If yes is checked, no should be 'unchecked' and vise-versa\r\n if (\r\n this.radioParent instanceof PowerPagesElement &&\r\n e &&\r\n e.type !== \"manual-radio-sync\"\r\n ) {\r\n switch (this.radioType) {\r\n case \"falsy\":\r\n this.radioParent.yesRadio!.setValue(!elementValue);\r\n await this.radioParent.yesRadio!.updateValue(\r\n new Event(\"manual-radio-sync\")\r\n );\r\n\r\n break;\r\n case \"truthy\":\r\n this.radioParent.noRadio!.setValue(!elementValue);\r\n await this.radioParent.noRadio!.updateValue(\r\n new Event(\"manual-radio-sync\")\r\n );\r\n\r\n break;\r\n }\r\n\r\n this.radioParent.updateValue();\r\n }\r\n }\r\n\r\n public getElementValue(): Promise<ElementValue> {\r\n return new Promise((resolve) => {\r\n const input = this.element as HTMLInputElement;\r\n const select = this.element as HTMLSelectElement;\r\n\r\n if (this.yesRadio instanceof Radio && this.noRadio instanceof Radio) {\r\n resolve({\r\n value: this.yesRadio.checked,\r\n checked: this.yesRadio.checked,\r\n });\r\n }\r\n\r\n let returnValue: ElementValue = {\r\n value: null,\r\n };\r\n switch (input.type) {\r\n case \"checkbox\":\r\n case \"radio\":\r\n resolve({\r\n value: input.checked,\r\n checked: input.checked,\r\n });\r\n break;\r\n case \"select-multiple\":\r\n resolve({\r\n value: Array.from(select.selectedOptions).map(\r\n (option) => option.value\r\n ),\r\n });\r\n break;\r\n\r\n case \"select-one\":\r\n resolve({\r\n value: select.value,\r\n });\r\n break;\r\n\r\n case \"number\":\r\n resolve({\r\n value: input.value !== \"\" ? Number(input.value) : null,\r\n });\r\n break;\r\n\r\n default: {\r\n let cleanValue: string | number = input.value;\r\n if (this.element!.classList.contains(\"decimal\")) {\r\n cleanValue = parseFloat(input.value.replace(/[$,]/g, \"\").trim());\r\n }\r\n\r\n returnValue = {\r\n value: cleanValue,\r\n };\r\n }\r\n }\r\n\r\n returnValue = {\r\n ...returnValue,\r\n value: this._validateValue(returnValue.value),\r\n };\r\n\r\n resolve(returnValue);\r\n });\r\n }\r\n\r\n protected _validateValue(value: any): any {\r\n if (typeof value === \"boolean\" || value === \"true\" || value === \"false\") {\r\n return value === true || value === \"true\";\r\n }\r\n\r\n // If it's a select element or text input (not decimal), return as is\r\n if (\r\n this.element instanceof HTMLSelectElement ||\r\n ((this.element as HTMLInputElement).type === \"text\" &&\r\n !(this.element as HTMLInputElement).classList.contains(\"decimal\"))\r\n ) {\r\n return value;\r\n }\r\n\r\n // Handle null/empty cases\r\n if (value === null || value === \"\") {\r\n return value;\r\n }\r\n\r\n if (!isNaN(Number(value))) {\r\n return Number(value);\r\n }\r\n\r\n return value;\r\n }\r\n\r\n public clearValue(): void {\r\n try {\r\n const element = this.element;\r\n\r\n // set 'default value' // effects date inputs primarily\r\n (element as HTMLInputElement).defaultValue = \"\";\r\n\r\n if (element instanceof HTMLInputElement) {\r\n switch (element.type.toLowerCase()) {\r\n case \"checkbox\":\r\n case \"radio\":\r\n element.checked = false;\r\n this.checked = false;\r\n this.value = false;\r\n break;\r\n\r\n case \"number\":\r\n element.value = \"\";\r\n this.value = null;\r\n break;\r\n\r\n default: // handles text, email, tel, etc.\r\n element.value = \"\";\r\n this.value = null;\r\n break;\r\n }\r\n } else if (element instanceof HTMLSelectElement) {\r\n if (element.multiple) {\r\n Array.from(element.options).forEach(\r\n (option) => (option.selected = false)\r\n );\r\n this.value = null;\r\n } else {\r\n element.selectedIndex = -1;\r\n this.value = null;\r\n }\r\n } else if (element instanceof HTMLTextAreaElement) {\r\n element.value = \"\";\r\n this.value = null;\r\n } else {\r\n this.value = null;\r\n }\r\n } catch (error) {\r\n const errorMessage = `Failed to clear values for element with target \"${this}\": ${\r\n error instanceof Error ? error.message : String(error)\r\n }`;\r\n throw new Error(errorMessage);\r\n }\r\n }\r\n\r\n public destroy(): void {\r\n this.value = null;\r\n this.checked = false;\r\n this.element = null;\r\n this.noRadio = undefined;\r\n this.yesRadio = undefined;\r\n this.isRadio = false;\r\n }\r\n}\r\n", "import InputMask from \"./InputMask.ts\";\r\n\r\ninterface MoneyInputMaskOptions extends InputMaskOptions {\r\n prefix: CurrencySymbol; // Currency symbol (e.g., \"$\")\r\n decimalPlaces: number; // Number of decimal places (default: 2)\r\n thousandsSeparator: string; // Character for separating thousands (e.g., \",\")\r\n decimalSeparator: string; // Character for decimal point (e.g., \".\")\r\n allowNegative: boolean; // Whether to allow negative values\r\n}\r\n\r\nexport default class MoneyMask extends InputMask {\r\n public input: HTMLInputElement;\r\n protected options: MoneyInputMaskOptions;\r\n private buffer: string = \"\";\r\n private charAtSelection: string | undefined = \"\";\r\n private charBeforeSelection: string | undefined = \"\";\r\n private lengthOf0FormattedValue: number;\r\n // Cache regex patterns\r\n private readonly digitRegex = /\\d/;\r\n private readonly nonDigitRegex = /\\D/g;\r\n private readonly thousandsRegex = /\\B(?=(\\d{3})+(?!\\d))/g;\r\n private readonly separatorRegex: RegExp;\r\n\r\n constructor(\r\n inputElement: HTMLInputElement,\r\n options: Partial<MoneyInputMaskOptions> = {}\r\n ) {\r\n super();\r\n this.input = inputElement;\r\n this.options = {\r\n prefix: options.prefix || \"$\",\r\n decimalPlaces: options.decimalPlaces ?? 2,\r\n thousandsSeparator: options.thousandsSeparator || \",\",\r\n decimalSeparator: options.decimalSeparator || \".\",\r\n allowNegative: options.allowNegative ?? true,\r\n };\r\n\r\n // Create escaped separator regex once during initialization\r\n const escapedThousands = this.escapeRegExp(this.options.thousandsSeparator);\r\n const escapedDecimal = this.escapeRegExp(this.options.decimalSeparator);\r\n this.separatorRegex = new RegExp(`[${escapedThousands}${escapedDecimal}]`);\r\n\r\n // Bind methods once\r\n this.onFocus = this.onFocus.bind(this);\r\n this.onInput = this.onInput.bind(this);\r\n this.onSelectionChange = this.onSelectionChange.bind(this);\r\n this.onBlur = this.onBlur.bind(this);\r\n\r\n // Calculate zero value length once\r\n this.lengthOf0FormattedValue = `0${\r\n this.options.decimalPlaces > 0\r\n ? this.options.decimalSeparator + \"0\".repeat(this.options.decimalPlaces)\r\n : \"\"\r\n }`.length;\r\n\r\n this.setupEventListeners();\r\n\r\n // Initialize with existing value if present\r\n if (this.input.value) {\r\n this.buffer = this.input.value.replace(this.nonDigitRegex, \"\");\r\n }\r\n\r\n // Initial formatting\r\n this.formatAndDisplay();\r\n }\r\n\r\n private escapeRegExp(string: string): string {\r\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n }\r\n\r\n private formatAndDisplay(): void {\r\n const numericValue = Number(this.buffer || \"0\");\r\n this.input.value = this.formatNumber(numericValue);\r\n }\r\n\r\n protected override setupEventListeners(): void {\r\n this.input.addEventListener(\"focus\", this.onFocus);\r\n this.input.addEventListener(\"input\", this.onInput);\r\n this.input.addEventListener(\"selectionchange\", this.onSelectionChange);\r\n this.input.addEventListener(\"blur\", this.onBlur);\r\n }\r\n\r\n protected formatInput(): void {\r\n const value = this.input.value;\r\n const caretPosition = this.input.selectionStart || 0;\r\n const oldLength = value.length;\r\n\r\n // Create allowed characters pattern only when needed\r\n const allowedPattern = new RegExp(\r\n `[^0-9${this.options.decimalSeparator}${\r\n this.options.allowNegative ? \"-\" : \"\"\r\n }]`,\r\n \"g\"\r\n );\r\n\r\n let cleanValue = value.replace(allowedPattern, \"\");\r\n\r\n // Ensure only one decimal separator\r\n const parts = cleanValue.split(this.options.decimalSeparator);\r\n if (parts.length > 2) {\r\n cleanValue =\r\n parts[0] + this.options.decimalSeparator + parts.slice(1).join(\"\");\r\n }\r\n\r\n // Handle negative sign\r\n if (this.options.allowNegative && cleanValue.indexOf(\"-\") > 0) {\r\n cleanValue = cleanValue.replace(/-/g, \"\");\r\n if (cleanValue.charAt(0) !== \"-\") {\r\n cleanValue = \"-\" + cleanValue;\r\n }\r\n }\r\n\r\n // Convert to number and format\r\n let numericValue: number;\r\n if (cleanValue === \"\" || cleanValue === \"-\") {\r\n numericValue = 0;\r\n } else {\r\n numericValue = parseFloat(\r\n cleanValue.replace(this.options.decimalSeparator, \".\")\r\n );\r\n }\r\n\r\n if (isNaN(numericValue)) {\r\n numericValue = 0;\r\n }\r\n\r\n // Format the number\r\n const formattedValue = this.formatNumber(numericValue);\r\n\r\n // Update the input value\r\n this.input.value = formattedValue;\r\n\r\n // Adjust caret position\r\n const newPosition = caretPosition + (formattedValue.length - oldLength);\r\n this.input.setSelectionRange(newPosition, newPosition);\r\n }\r\n\r\n protected formatNumber(value: number): string {\r\n const adjustedValue = value / 10 ** this.options.decimalPlaces;\r\n const isNegative = adjustedValue < 0;\r\n const absoluteValue = Math.abs(adjustedValue);\r\n\r\n // Format with fixed decimal places\r\n const formatted = absoluteValue.toFixed(this.options.decimalPlaces);\r\n const [integerPart, decimalPart] = formatted.split(\".\");\r\n\r\n // Add thousands separators\r\n const formattedInteger = integerPart.replace(\r\n this.thousandsRegex,\r\n this.options.thousandsSeparator\r\n );\r\n\r\n // Combine parts\r\n return (\r\n (isNegative ? \"-\" : \"\") +\r\n this.options.prefix +\r\n formattedInteger +\r\n (this.options.decimalPlaces > 0\r\n ? this.options.decimalSeparator + decimalPart\r\n : \"\")\r\n );\r\n }\r\n\r\n protected onSelectionChange(_e: Event): void {\r\n const position = this.input.selectionStart as number;\r\n this.charAtSelection = this.input.value[position];\r\n this.charBeforeSelection = this.input.value[position - 1];\r\n }\r\n\r\n protected onInput(_e: Event): void {\r\n const e = _e as InputEvent;\r\n const formattedValue: string = this.input.value;\r\n const caretPosition: number = this.input.selectionStart ?? 0;\r\n\r\n // Calculate the raw index: count only digits before the caret\r\n const rawIndex = formattedValue\r\n .slice(0, caretPosition)\r\n .replace(this.nonDigitRegex, \"\").length;\r\n\r\n let newRawIndex = rawIndex;\r\n\r\n switch (e.inputType) {\r\n case \"insertText\":\r\n // Handle text insertion\r\n this.buffer =\r\n this.buffer.slice(0, rawIndex - 1) +\r\n (e.data || \"\").replace(this.nonDigitRegex, \"\") +\r\n this.buffer.slice(rawIndex - 1);\r\n\r\n newRawIndex = rawIndex;\r\n break;\r\n\r\n case \"deleteContentBackward\":\r\n // Handle backspace\r\n if (rawIndex >= 0) {\r\n if (this.separatorRegex.test(this.charBeforeSelection as string)) {\r\n this.buffer =\r\n this.buffer.slice(0, rawIndex - 1) + this.buffer.slice(rawIndex);\r\n newRawIndex = rawIndex - 1;\r\n } else {\r\n this.buffer =\r\n this.buffer.slice(0, rawIndex) + this.buffer.slice(rawIndex + 1);\r\n newRawIndex = rawIndex;\r\n }\r\n } else if (formattedValue === \"\") {\r\n this.buffer = \"\";\r\n }\r\n break;\r\n\r\n case \"deleteContentForward\":\r\n // Handle delete key\r\n if (rawIndex < this.buffer.length) {\r\n this.buffer =\r\n this.buffer.slice(0, rawIndex) + this.buffer.slice(rawIndex + 1);\r\n }\r\n break;\r\n\r\n case \"deleteWordBackward\":\r\n case \"deleteWordForward\":\r\n // Handle word deletion\r\n this.buffer = \"\";\r\n newRawIndex = this.lengthOf0FormattedValue;\r\n break;\r\n\r\n default:\r\n // Fallback for other input types\r\n this.buffer = formattedValue.replace(this.nonDigitRegex, \"\");\r\n newRawIndex = this.buffer.length;\r\n }\r\n\r\n // Format and update the display\r\n const numericValue = Number(this.buffer || \"0\");\r\n const newFormattedValue = this.formatNumber(numericValue);\r\n this.input.value = newFormattedValue;\r\n\r\n // Update caret position\r\n const newCaretPosition = this.mapRawIndexToFormattedPosition(\r\n newRawIndex,\r\n newFormattedValue\r\n );\r\n\r\n this.input.setSelectionRange(newCaretPosition, newCaretPosition);\r\n }\r\n\r\n private mapRawIndexToFormattedPosition(\r\n rawIndex: number,\r\n formatted: string\r\n ): number {\r\n let digitCount = 0;\r\n for (let i = 0; i < formatted.length; i++) {\r\n if (this.digitRegex.test(formatted[i])) {\r\n digitCount++;\r\n }\r\n if (digitCount === rawIndex) {\r\n return i + 1;\r\n }\r\n }\r\n return formatted.length;\r\n }\r\n\r\n protected override onFocus(): void {\r\n // Debounce selection to avoid race conditions\r\n setTimeout(() => this.input.select(), 0);\r\n }\r\n\r\n protected override onBlur(): void {\r\n // Format on blur\r\n const numericValue = Number(this.buffer || \"0\");\r\n this.input.value = this.formatNumber(numericValue);\r\n\r\n // Reset to zero if needed\r\n if (numericValue === 0) {\r\n this.buffer = \"\";\r\n const zeros = \"0\".repeat(this.options.decimalPlaces);\r\n this.input.value = `${this.options.prefix}0${\r\n this.options.decimalPlaces > 0\r\n ? this.options.decimalSeparator + zeros\r\n : \"\"\r\n }`;\r\n }\r\n }\r\n\r\n // Get the numerical value\r\n public getNumericalValue(): number {\r\n return Number(this.buffer || \"0\") / 10 ** this.options.decimalPlaces;\r\n }\r\n\r\n // Set a new numerical value\r\n public override setValue(value: number): void {\r\n const scaledValue = Math.round(\r\n Math.abs(value) * 10 ** this.options.decimalPlaces\r\n );\r\n\r\n this.buffer = scaledValue.toString();\r\n this.input.value = this.formatNumber(scaledValue);\r\n }\r\n\r\n public destroy(): void {\r\n this.input.removeEventListener(\"focus\", this.onFocus);\r\n this.input.removeEventListener(\"input\", this.onInput);\r\n this.input.removeEventListener(\"selectionchange\", this.onSelectionChange);\r\n this.input.removeEventListener(\"blur\", this.onBlur);\r\n }\r\n}\r\n", "import VisibilityManager from \"../ancillary/VisibilityManager.ts\";\r\nimport DOMNodeReference from \"../ancillary/DOMNodeReference.ts\";\r\nimport PhoneNumberMask from \"../utils/PhoneNumberMask.ts\";\r\nimport EventManager from \"../ancillary/EventManager.ts\";\r\nimport ValueManager from \"../ancillary/ValueManager.ts\";\r\nimport { init, destroy } from \"../constants/symbols.ts\";\r\nimport type InputMask from \"../utils/InputMask.ts\";\r\nimport MoneyInputMask from \"../utils/MoneyMask.ts\";\r\nimport Radio from \"../ancillary/Radio.ts\";\r\nimport Errors from \"../errors/errors.ts\";\r\n\r\n/********/ /********/ export default class PowerPagesElement extends DOMNodeReference {\r\n // allow for indexing methods with symbols\r\n [key: symbol]: (...arg: any[]) => any;\r\n private isMasked: boolean = false;\r\n\r\n /**\r\n * Represents the 'yes' option of a boolean radio field.\r\n * This property is only available when the parent node\r\n * is a main field for a boolean radio input.\r\n */\r\n public yesRadio: Radio | undefined;\r\n /**\r\n * Represents the 'no' option of a boolean radio field.\r\n * This property is only available when the parent node\r\n * is a main field for a boolean radio input.\r\n */\r\n public noRadio: Radio | undefined;\r\n\r\n /**\r\n * Creates an instance of PowerPagesElement.\r\n * @param target - The CSS selector to find the desired DOM element.\r\n * @param root - Optionally specify the element within to search for the element targeted by 'target'\r\n * Defaults to 'document.body'\r\n */\r\n /******/ constructor(\r\n target: Element | string,\r\n root: Element = document.body,\r\n timeoutMs: number\r\n ) {\r\n super(target, root, timeoutMs);\r\n }\r\n\r\n //\r\n public async [init](): Promise<void> {\r\n /**\r\n * dynamically define the s.init method using our custom symbol\r\n * this makes it so that the s.init method cannot be accessed outside\r\n * of this package: i.e. by any consumers of the package\r\n */\r\n try {\r\n await super[init]();\r\n\r\n if (\r\n this.element.id &&\r\n this.element.querySelectorAll(\r\n `#${this.element.id} > input[type=\"radio\"]`\r\n ).length > 0\r\n ) {\r\n await this._attachRadioButtons();\r\n }\r\n\r\n this.initEventManager();\r\n this.initVisibilityManager();\r\n this.initValueManager();\r\n\r\n // we want to ensure that all method calls from the consumer have access to 'this'\r\n this._bindMethods();\r\n\r\n // when the element is removed from the DOM, destroy this\r\n const observer = new MutationObserver((mutations) => {\r\n for (const mutation of mutations) {\r\n if (Array.from(mutation.removedNodes).includes(this.element)) {\r\n if (typeof this[destroy] === \"function\") this[destroy]();\r\n observer.disconnect();\r\n break;\r\n }\r\n }\r\n });\r\n\r\n observer.observe(document.body, {\r\n childList: true,\r\n subtree: true,\r\n });\r\n\r\n PowerPagesElement.instances.push(this);\r\n\r\n this.isLoaded = true;\r\n } catch (error) {\r\n const errorMessage: string =\r\n error instanceof Error ? error.message : String(error);\r\n throw new Errors.InitializationError(this, errorMessage);\r\n }\r\n }\r\n\r\n protected override initValueManager(): void {\r\n this.valueManager = new ValueManager(this);\r\n\r\n this._valueSync();\r\n }\r\n protected override initVisibilityManager(): void {\r\n this.visibilityManager = new VisibilityManager(this.element);\r\n }\r\n protected override initEventManager(): void {\r\n this.eventManager = new EventManager();\r\n }\r\n\r\n protected async _attachRadioButtons(): Promise<void> {\r\n if (!this.element) {\r\n console.error(\r\n \"'this.element' not found: cannot attach radio buttons for \",\r\n this.target\r\n );\r\n return;\r\n }\r\n\r\n this.yesRadio = new Radio(\r\n this,\r\n 'input[type=\"radio\"][value=\"1\"]',\r\n this.element,\r\n 0,\r\n \"truthy\"\r\n );\r\n\r\n this.noRadio = new Radio(\r\n this,\r\n 'input[type=\"radio\"][value=\"0\"]',\r\n this.element,\r\n 0,\r\n \"falsy\"\r\n );\r\n\r\n await this.yesRadio[init]();\r\n await this.noRadio[init]();\r\n }\r\n\r\n public override clearValue(): void {\r\n // Handle radio button group if present\r\n if (this.yesRadio instanceof Radio && this.noRadio instanceof Radio) {\r\n this.yesRadio.clearValue();\r\n this.noRadio.clearValue();\r\n }\r\n super.clearValue();\r\n }\r\n\r\n /**\r\n * Unchecks both the yes and no radio buttons if they exist.\r\n * @returns - Instance of this [provides option to method chain]\r\n */\r\n public uncheckRadios(): PowerPagesElement {\r\n if (\r\n this.yesRadio instanceof DOMNodeReference &&\r\n this.noRadio instanceof DOMNodeReference\r\n ) {\r\n (this.yesRadio.element as HTMLInputElement).checked = false;\r\n (this.noRadio.element as HTMLInputElement).checked = false;\r\n } else {\r\n console.error(\r\n \"[SYNACT] Attempted to uncheck radios for an element that has no radios\"\r\n );\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Apply an input mask to this element\r\n * @param type The type of input mask to apply to this element\r\n * @param options The options to specify the behavior of the mask\r\n */\r\n public inputMask(type: \"phone\" | \"money\", options: InputMaskOptions): void;\r\n public inputMask(\r\n type: \"phone\",\r\n options?: {\r\n format?: PhoneNumberFormats;\r\n countryCode?: CountryCodeFormats;\r\n }\r\n ): void;\r\n public inputMask(\r\n type: \"money\",\r\n options?: {\r\n prefix?: CurrencySymbol; // Currency symbol (e.g., \"$\")\r\n decimalPlaces?: number; // Number of decimal places (default: 2)\r\n thousandsSeparator?: string; // Character for separating thousands (e.g., \",\")\r\n decimalSeparator?: string; // Character for decimal point (e.g., \".\")\r\n allowNegative?: boolean; // Whether to allow negative values\r\n }\r\n ): void;\r\n public inputMask(\r\n type: \"money\" | \"phone\",\r\n options: InputMaskOptions\r\n ): PowerPagesElement {\r\n if (this.isMasked) {\r\n throw new Error(\r\n `You cannot apply multiple input masks to the same element. @${this.target}`\r\n );\r\n }\r\n\r\n let newMask: InputMask;\r\n switch (type) {\r\n case \"money\":\r\n newMask = new MoneyInputMask(this.element as HTMLInputElement, options);\r\n break;\r\n case \"phone\":\r\n newMask = new PhoneNumberMask(\r\n this.element as HTMLInputElement,\r\n options\r\n );\r\n break;\r\n default:\r\n throw new Error(\r\n `No type provided for 'inputMask()' at: ${this.target}`\r\n );\r\n }\r\n\r\n this.valueManager!.element = newMask.input;\r\n this.isMasked = true;\r\n\r\n return this;\r\n }\r\n\r\n protected [destroy](): void {\r\n super[destroy]();\r\n // Destroy radio buttons if they exist\r\n this.yesRadio?.[destroy]();\r\n this.noRadio?.[destroy]();\r\n this.yesRadio = undefined;\r\n this.noRadio = undefined;\r\n }\r\n}\r\n", "import type PowerPagesElement from \"./PowerPagesElement.ts\";\r\n\r\nexport default class PowerPagesElementArray extends Array<PowerPagesElement> {\r\n /**\r\n * Hides all the containers of the PowerPagesElement instances in the array.\r\n */\r\n hideAll(this: PowerPagesElementArray) {\r\n this.forEach((instance: PowerPagesElement) => instance.hide());\r\n return this;\r\n }\r\n\r\n /**\r\n * Shows all the containers of the PowerPagesElement instances in the array.\r\n */\r\n\r\n showAll(this: PowerPagesElementArray) {\r\n this.forEach((instance: PowerPagesElement) => instance.show());\r\n return this;\r\n }\r\n}\r\n", "import PowerPagesElementArray from \"../core/PowerPagesElementArray.ts\";\r\nimport type PowerPagesElement from \"../core/PowerPagesElement.ts\";\r\n\r\n/**\r\n *\r\n * @param array An array of PowerPagesElements to be modified with custom methods, as well as a custom getter. Custom getter allows for accessing properties within the array with bracket-style property access. See example\r\n * @example\r\n * ```javascript\r\n * const enhanced = enhanceArray(basicArray)\r\n * const someProp = enhanced['some_prop_logical_name']\r\n * ```\r\n */\r\nexport default function enhanceArray<T extends string>(\r\n array: PowerPagesElement[]\r\n): PowerPagesElementArray & Record<T, PowerPagesElement> {\r\n const enhancedArray = new PowerPagesElementArray(...array);\r\n\r\n return new Proxy(enhancedArray, {\r\n get(target, prop: string | symbol, receiver) {\r\n // Preserve existing array methods\r\n if (prop in target) {\r\n return Reflect.get(target, prop, receiver);\r\n }\r\n\r\n // Ensure `prop` is a string and search by `element.id`\r\n if (typeof prop === \"string\") {\r\n return target.find(\r\n (instance) =>\r\n instance.target.toString().replace(/[#\\[\\]]/g, \"\") === prop ||\r\n instance.logicalName === prop\r\n );\r\n }\r\n\r\n return undefined;\r\n },\r\n }) as PowerPagesElementArray & Record<T, PowerPagesElement>;\r\n}\r\n", "import type PowerPagesElementArray from \"./PowerPagesElementArray.ts\";\r\nimport PowerPagesElement from \"./PowerPagesElement.ts\";\r\nimport enhanceArray from \"../utils/enhanceArray.ts\";\r\nimport waitFor from \"./waitFor.ts\";\r\nimport { init } from \"../constants/symbols.ts\";\r\n\r\n// Add function overloads to clearly specify return types based on the 'multiple' parameter\r\n/**\r\n * Creates and initializes a PowerPagesElement instance.\r\n * @see {@link CreationOptions}\r\n * @param **target** - The selector, using `querySelector` syntax, for the desired DOM element. Or, the `HTMLElement` itself for which to create a PowerPagesElement.\r\n * @param **options** - Options for advanced retrieval of elements\r\n * @param **options.multiple** - Should this call return an array of instantiated references, or just a single? Defaults to false, returning a single instance\r\n * @param **options.root** - Optionally specify the element within to search for the element targeted by 'target'. Defaults to `document.body`\r\n * @param **options.timeoutMs** - Optionally specify the amount of time that should be waited to find the targeted element before throwing error - useful for async DOM loading. Relies on MutationObserver. ***WARNING***: Implementing multiple references with timeout can result in infinite loading.\r\n * @returns A promise that resolves to a Proxy of the initialized PowerPagesElement instance.\r\n *\r\n * @see {@link PowerPagesElement}\r\n * @see {@link PowerPagesElementArray}\r\n * @see {@link enhanceArray}\r\n */\r\n\r\nexport default async function createPowerPagesElement(\r\n target: string | Element\r\n): Promise<PowerPagesElement>;\r\nexport default async function createPowerPagesElement(\r\n target: Element\r\n): Promise<PowerPagesElement>;\r\nexport default async function createPowerPagesElement(\r\n target: string,\r\n options?: {\r\n /**\r\n * Optionally specify the element within which to search for the element targeted by 'target'.\r\n * Defaults to 'document.body'.\r\n */\r\n root?: HTMLElement;\r\n /**\r\n * Optionally specify the amount of time that should be waited to find the targeted element before throwing an error.\r\n * Useful for async DOM loading. Relies on MutationObserver.\r\n * WARNING: Implementing multiple references with timeout can result in infinite loading.\r\n */\r\n timeoutMs?: number;\r\n }\r\n): Promise<PowerPagesElement>;\r\n\r\nexport default async function createPowerPagesElement(\r\n target: string,\r\n options?: {\r\n /**\r\n * Should this call return an array of instantiated references, or just a single?\r\n * Defaults to false, returning a single instance.\r\n */\r\n multiple?: true;\r\n /**\r\n * Optionally specify the element within which to search for the element targeted by 'target'.\r\n * Defaults to 'document.body'.\r\n */\r\n root?: HTMLElement;\r\n /**\r\n * Optionally specify the amount of time that should be waited to find the targeted element before throwing an error.\r\n * Useful for async DOM loading. Relies on MutationObserver.\r\n * WARNING: Implementing multiple references with timeout can result in infinite loading.\r\n */\r\n timeoutMs?: number;\r\n }\r\n): Promise<PowerPagesElementArray>;\r\n\r\nexport default async function createPowerPagesElement(\r\n target: Element | string,\r\n options: CreationOptions = {\r\n multiple: false,\r\n root: document.body,\r\n timeoutMs: 0,\r\n }\r\n): Promise<PowerPagesElement | PowerPagesElementArray> {\r\n try {\r\n if (typeof options !== \"object\") {\r\n throw new TypeError(\r\n `'options' must be of type 'object'. Received type: '${typeof options}'`\r\n );\r\n }\r\n\r\n validateOptions(options);\r\n const { multiple = false, root = document.body, timeoutMs = 0 } = options;\r\n\r\n // Evaluate multiple parameter once at the start\r\n const isMultiple = typeof multiple === \"function\" ? multiple() : multiple;\r\n\r\n if (isMultiple) {\r\n if (typeof target !== \"string\") {\r\n throw new TypeError(\r\n `'target' must be of type 'string' if 'multiple' is set to 'true'. Received type: '${typeof target}'`\r\n );\r\n }\r\n\r\n const elements = <HTMLElement[]>(\r\n await waitFor(target, root, true, timeoutMs)\r\n );\r\n\r\n // Avoid recursive call with multiple flag for better performance\r\n const initializedElements = <PowerPagesElementArray>await Promise.all(\r\n elements.map(async (element) => {\r\n const instance = new PowerPagesElement(element, root, timeoutMs);\r\n await instance[init]();\r\n return new Proxy(instance, createProxyHandler());\r\n })\r\n );\r\n return enhanceArray(initializedElements);\r\n }\r\n\r\n const instance = new PowerPagesElement(target, root, timeoutMs);\r\n await instance[init]();\r\n return new Proxy(instance, createProxyHandler());\r\n } catch (error) {\r\n if (error instanceof Error) throw error;\r\n else throw new Error(\"Failed to get DOM Node by target: \" + target);\r\n }\r\n}\r\n\r\nexport function validateOptions(options: Partial<CreationOptions>) {\r\n const { multiple = false, root = document.body, timeoutMs = 0 } = options;\r\n if (typeof multiple !== \"boolean\" && typeof multiple !== \"function\") {\r\n throw new TypeError(\r\n `'multiple' must be of type 'boolean' or 'function'. Received type: '${typeof multiple}'`\r\n );\r\n }\r\n if (typeof multiple === \"function\") {\r\n const value = multiple();\r\n if (typeof value !== \"boolean\") {\r\n throw new TypeError(\r\n `'multiple' function must return a boolean. Received type: '${typeof value}'`\r\n );\r\n }\r\n }\r\n if (!(root instanceof HTMLElement)) {\r\n throw new TypeError(\r\n `'root' must be of type 'HTMLElement'. Received type: '${typeof root}'`\r\n );\r\n }\r\n if (typeof timeoutMs !== \"number\") {\r\n throw new TypeError(\r\n `'timeout' must be of type 'number'. Received type: '${typeof timeoutMs}'`\r\n );\r\n }\r\n return;\r\n}\r\n\r\n// Separate proxy handler for reusability\r\nexport function createProxyHandler() {\r\n return {\r\n get: (target: PowerPagesElement, prop: string | symbol) => {\r\n if (prop.toString().startsWith(\"_\")) return undefined;\r\n\r\n const value = target[<keyof PowerPagesElement>prop];\r\n if (typeof value === \"function\" && prop !== \"onceLoaded\") {\r\n return (...args: any[]) => {\r\n target.onceLoaded(() => value.apply(target, args));\r\n return target;\r\n };\r\n }\r\n return value;\r\n },\r\n };\r\n}\r\n", "import type PowerPagesElementArray from \"./PowerPagesElementArray.ts\";\r\nimport type PowerPagesElement from \"./PowerPagesElement.ts\";\r\nimport enhanceArray from \"../utils/enhanceArray.ts\";\r\nimport get from \"./getPowerPagesElement.ts\";\r\nimport API from \"./API.ts\";\r\n\r\n/**\r\n * When loading into a page in PowerPages that has a form,\r\n * you can use this function by passing in the GUID of the form, and you will receive an array/record\r\n * of {@link PowerPagesElement}s that represent all fields, sections, sub-grids, and tabs of the given form.\r\n * Access these properties of the {@link BoundForm} using the logical name of the control you need to access: form['logical_name']\r\n * you can then execute all the methods available from PowerPagesElement\r\n * @param formId - The string GUID of the form you want to bind to\r\n * @returns An array of PowerPagesElements, accessible as properties of a Record<string, PowerPagesElement> i.e. formProp = form[\"some_logicalName\"]\r\n * @example\r\n * ```js\r\n * bindForm(\"form-guid-0000\").then((form) => {\r\n * //...use the form\r\n * const field = form[\"field_logical_name\"]\r\n * // or\r\n * form[\"other_logical_name\"].someMethod()\r\n * })\r\n *\r\n * // or\r\n *\r\n * const form = await bindForm(\"form-guid-0000\")\r\n * ```\r\n * @see {@link BoundForm}\r\n * @see {@link PowerPagesElement}\r\n */\r\nexport default async function bindForm(\r\n formId: string\r\n): Promise<PowerPagesElementArray & Record<string, PowerPagesElement>> {\r\n try {\r\n const form = await API.getRecord<Form>(\"systemforms\", formId);\r\n const { formxml } = form;\r\n\r\n /**\r\n * since the form is coming in as a string containing XML\r\n * We have to set up a parser to extract the information we need\r\n */\r\n const parser = new DOMParser(); // establish the parser\r\n const xmlDoc = parser.parseFromString(formxml, \"application/xml\"); // parse the XML\r\n /**\r\n * Then we can get the attributes we want from the parsed XML\r\n */\r\n const controls = processElements(xmlDoc.getElementsByTagName(\"control\")); // get control elements (will represent columns in the form)\r\n const sections = processElements(xmlDoc.getElementsByTagName(\"section\")); // self explanatory\r\n const tabs = processElements(xmlDoc.getElementsByTagName(\"tab\")); // self explanatory\r\n\r\n // Resolve all promises, filtering out any null values\r\n const resolvedRefs = await Promise.all([...controls, ...sections, ...tabs]);\r\n /**\r\n * Then, finally, 'enhance' the array, adding custom methods and a custom 'getter'\r\n * which will allow us to access individual nodes using the syntax `array[\"logical_name\"]`\r\n */\r\n return enhanceArray(\r\n resolvedRefs.filter((ref): ref is PowerPagesElement => ref !== null)\r\n );\r\n /** handle errors */\r\n } catch (error: unknown) {\r\n if (error instanceof Error) {\r\n console.error(error.message);\r\n throw error; // Re-throw the original error to keep stack trace\r\n } else {\r\n console.error(error);\r\n throw new Error(String(error)); // Ensure non-Error values are converted to a string\r\n }\r\n }\r\n}\r\n\r\nfunction processElements(element: HTMLCollectionOf<Element>) {\r\n return Array.from(element)\r\n .map((element) => {\r\n // use a helper function to determine the attribute we want based on the tagname of the element\r\n const identifyingAttribute = getIdentifyingAttribute(element.tagName);\r\n const datafieldname = element.getAttribute(identifyingAttribute);\r\n // if we don't find the desired thing,\r\n if (!datafieldname) return null;\r\n\r\n const referenceString: string | null = createReferenceString(\r\n element.tagName,\r\n datafieldname\r\n );\r\n if (!referenceString) return null;\r\n\r\n return get(referenceString).catch((error) => {\r\n console.warn(\r\n `Failed to create a reference to the form field: ${datafieldname}`,\r\n error\r\n );\r\n return null;\r\n });\r\n })\r\n .filter(Boolean); // Remove null values\r\n}\r\n\r\nfunction getIdentifyingAttribute(tagName: string): string {\r\n return tagName === \"control\"\r\n ? \"id\"\r\n : tagName === \"tab\" || tagName === \"section\"\r\n ? \"name\"\r\n : \"id\";\r\n}\r\n\r\nfunction createReferenceString(\r\n tagName: string,\r\n datafieldname: string\r\n): string | null {\r\n if (tagName === \"control\") return `#${datafieldname}`;\r\n if (tagName === \"tab\" || tagName === \"section\") {\r\n return `[data-name=\"${datafieldname}\"]`;\r\n }\r\n return null; // Explicitly return null instead of undefined\r\n}\r\n", "/**\r\n * @class LoadingSpinner - instantiate a spinner to handle loading state in your powerpages site\r\n */\r\n/********/ /********/ export default class LoadingSpinner extends HTMLElement {\r\n private element!: HTMLDivElement;\r\n constructor() {\r\n if (!document) {\r\n throw new Error(`Cannot instantiate 'LoadingSpinner': No DOM Found`);\r\n }\r\n super();\r\n this.id = \"loader\";\r\n this.classList.add(\"loader-overlay\", \"hidden\");\r\n\r\n this.element = document.createElement(\"div\");\r\n this.element.classList.add(\"spinner-border\", \"text-light\");\r\n this.element.role = \"status\";\r\n this.appendChild(this.element);\r\n\r\n const span: HTMLSpanElement = document.createElement(\"span\");\r\n span.classList.add(\"visually-hidden\");\r\n span.textContent = \"Loading...\";\r\n this.element.appendChild(span);\r\n\r\n // finally add this to the DOM\r\n document.body.appendChild(this);\r\n }\r\n\r\n /**\r\n * @method hide - Hides the loading spinner\r\n */\r\n public hide(): void {\r\n this.classList.add(\"hidden\");\r\n }\r\n\r\n /**\r\n * @method show - Shows the loading spinner\r\n */\r\n public show(): void {\r\n this.classList.remove(\"hidden\");\r\n }\r\n}\r\n\r\nconst uid: string = `loading-${crypto.randomUUID()}`;\r\ncustomElements.define(uid, LoadingSpinner);\r\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["safeAjax", "options", "deferredAjax", "token", "data", "textStatus", "jqXHR", "API", "tableSetName", "data", "resolve", "reject", "safeAjax", "_response", "_status", "xhr", "error", "recordID", "ODataQueryString", "url", "query", "options", "success", "queryParameters", "response", "recordId", "API_default", "VisibilityManager", "newValue", "target", "fieldset", "tdParent", "shouldShow", "EventTypes", "init", "destroy", "InfoElement", "titleString", "iconStyle", "_destroy_observer", "mutations", "mut", "node", "_position_observer", "viewportWidth", "iconRect", "flyoutRect", "viewportHeight", "topPosition", "_e", "event", "relatedTarget", "previousFlyoutDisplay", "obv", "uid", "waitFor", "target", "root", "multiple", "debounceTime", "resolve", "reject", "timeout", "observedElements", "observedSet", "observer", "element", "observedElement", "CustomError", "node", "message", "InitializationError", "error", "NodeNotFoundError", "Page_ValidatorsNotFoundError", "BusinessRuleError", "SelfReferenceError", "LabelNotFoundError", "IncorrectParameterError", "functionName", "argName", "expectedTypes", "receivedType", "concatTypes", "Errors", "errors_default", "DOMPurify", "DOMNodeReference", "_DOMNodeReference", "newValue", "target", "root", "timeoutMs", "init", "waitFor", "errors_default", "bracketMatch", "content", "eventType", "EventTypes", "element", "parentElement", "dateNode", "prototype", "key", "value", "destroy", "eventHandler", "handler", "shouldShow", "bool", "child", "childIds", "input", "children", "ref", "callback", "elements", "label", "innerHTML", "containerStyle", "safeHTML", "InfoElement", "options", "prop", "rule", "dependencies", "error", "requirements", "isRequired", "isValid", "evaluationFunction", "isFieldRequired", "isFieldVisible", "clearValues", "isVisible", "condition", "finalValue", "fieldDisplayName", "validatorId", "newValidator", "dependency", "observer", "InputMask", "value", "PhoneNumberMask", "InputMask", "inputElement", "options", "value", "caretPosition", "oldLength", "digits", "formattedValue", "newPosition", "phoneDigits", "countryCodeValue", "countryCodeLength", "formattedCountryCode", "result", "digitIndex", "i", "lastNonFormatChar", "char", "index", "minLength", "cleanDigits", "countryDigits", "EventManager", "dependency", "handler", "event", "listener", "listeners", "eventType", "args", "_event", "observer", "observerOptions", "nodeToObserve", "options", "element", "binding", "Radio", "DOMNodeReference", "parent", "target", "root", "timeoutMs", "radioType", "init", "observer", "mutations", "mutation", "destroy", "error", "errorMessage", "errors_default", "EventManager", "ValueManager", "VisibilityManager", "ValueManager", "instance", "PowerPagesElement", "Radio", "value", "validatedValue", "elementValue", "resolve", "input", "select", "returnValue", "option", "cleanValue", "element", "error", "errorMessage", "MoneyMask", "InputMask", "inputElement", "options", "escapedThousands", "escapedDecimal", "string", "numericValue", "value", "caretPosition", "oldLength", "allowedPattern", "cleanValue", "parts", "formattedValue", "newPosition", "adjustedValue", "isNegative", "formatted", "integerPart", "decimalPart", "formattedInteger", "_e", "position", "e", "rawIndex", "newRawIndex", "newFormattedValue", "newCaretPosition", "digitCount", "i", "zeros", "scaledValue", "PowerPagesElement", "_PowerPagesElement", "DOMNodeReference", "target", "root", "timeoutMs", "init", "observer", "mutations", "mutation", "destroy", "error", "errorMessage", "errors_default", "ValueManager", "VisibilityManager", "EventManager", "Radio", "type", "options", "newMask", "MoneyMask", "PhoneNumberMask", "PowerPagesElementArray", "instance", "enhanceArray", "array", "enhancedArray", "PowerPagesElementArray", "target", "prop", "receiver", "instance", "createPowerPagesElement", "target", "options", "validateOptions", "multiple", "root", "timeoutMs", "elements", "waitFor", "initializedElements", "element", "instance", "PowerPagesElement", "init", "createProxyHandler", "enhanceArray", "error", "value", "prop", "args", "bindForm", "formId", "form", "API_default", "formxml", "xmlDoc", "controls", "processElements", "sections", "tabs", "resolvedRefs", "enhanceArray", "ref", "error", "element", "identifyingAttribute", "getIdentifyingAttribute", "datafieldname", "referenceString", "createReferenceString", "createPowerPagesElement", "tagName", "LoadingSpinner", "span", "uid"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "powerpagestoolkit",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.5011",
|
|
4
4
|
"description": "Reference, manipulate, and engage with Power Pages sites through the nodes in the DOM; use a variety of custom methods that allow customizing your power pages site quicker and easier. ",
|
|
5
5
|
"main": "./dist/src/index.js",
|
|
6
6
|
"module": "./dist/src/index.js",
|