diff --git a/modules/backend/assets/ui/js/build/backend.js b/modules/backend/assets/ui/js/build/backend.js index 251900720e..19db9916e8 100644 --- a/modules/backend/assets/ui/js/build/backend.js +++ b/modules/backend/assets/ui/js/build/backend.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_wintercms_wn_backend_module=self.webpackChunk_wintercms_wn_backend_module||[]).push([[476],{286:function(e,t,n){var i=n(35),r=n(171);class s extends Snowboard.Singleton{listens(){return{ready:"ready",ajaxFetchOptions:"ajaxFetchOptions",ajaxUpdateComplete:"ajaxUpdateComplete"}}ready(){window.jQuery&&((0,r.M)("render"),document.addEventListener("$render",(()=>{this.snowboard.globalEvent("render")})),window.jQuery(document).trigger("render"))}addPrefilter(){window.jQuery&&window.jQuery.ajaxPrefilter((e=>{this.hasToken()&&(e.headers||(e.headers={}),e.headers["X-CSRF-TOKEN"]=this.getToken())}))}ajaxFetchOptions(e){this.hasToken()&&(e.headers["X-CSRF-TOKEN"]=this.getToken())}ajaxUpdateComplete(){window.jQuery&&window.jQuery(document).trigger("render")}hasToken(){const e=document.querySelector('meta[name="csrf-token"]');return!!e&&!!e.hasAttribute("content")}getToken(){return document.querySelector('meta[name="csrf-token"]').getAttribute("content")}}class a extends Snowboard.PluginBase{construct(e,t){if(e instanceof Snowboard.PluginBase==!1)throw new Error("Event handling can only be applied to Snowboard classes.");if(!t)throw new Error("Event prefix is required.");this.instance=e,this.eventPrefix=t,this.events=[]}on(e,t){this.events.push({event:e,callback:t})}off(e,t){this.events=this.events.filter((n=>n.event!==e||n.callback!==t))}once(e,t){var n=this;const i=this.events.push({event:e,callback:function(){t(...arguments),n.events.splice(i-1,1)}})}fire(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),i=1;it.event===e));let s=!1;r.forEach((e=>{s||!1===e.callback(...n)&&(s=!0)})),s||this.snowboard.globalEvent(`${this.eventPrefix}.${e}`,...n)}firePromise(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),i=1;it.event===e)),s=r.filter((e=>null!==e),r.map((e=>e.callback(...n))));Promise.all(s).then((()=>{this.snowboard.globalPromiseEvent(`${this.eventPrefix}.${e}`,...n)}))}}class o extends Snowboard.Singleton{construct(){this.registeredWidgets=[],this.elements=[],this.events={mutate:e=>this.onMutation(e)},this.observer=null}listens(){return{ready:"onReady",render:"onRender",ajaxUpdate:"onAjaxUpdate"}}register(e,t,n){this.registeredWidgets.push({control:e,widget:t,callback:n})}unregister(e){this.registeredWidgets=this.registeredWidgets.filter((t=>t.control!==e))}onReady(){this.initializeWidgets(document.body),this.observer||(this.observer=new MutationObserver(this.events.mutate),this.observer.observe(document.body,{childList:!0,subtree:!0}))}onRender(){this.initializeWidgets(document.body)}onAjaxUpdate(e){this.initializeWidgets(e)}initializeWidgets(e){this.registeredWidgets.forEach((t=>{const n=e.querySelectorAll(`[data-control="${t.control}"]:not([data-widget-initialized])`);n.length&&n.forEach((e=>{if(e.dataset.widgetInitialized)return;const n=this.snowboard[t.widget](e);this.elements.push({element:e,instance:n}),e.dataset.widgetInitialized=!0,this.snowboard.globalEvent("backend.widget.initialized",e,n),"function"==typeof t.callback&&t.callback(n,e)}))}))}getWidget(e){const t=this.elements.find((t=>t.element===e));return t?t.instance:null}onMutation(e){const t=e.filter((e=>e.removedNodes.length)).map((e=>Array.from(e.removedNodes))).flat();t.length&&t.forEach((e=>{const t=this.elements.filter((t=>e.contains(t.element)));t.length&&t.forEach((e=>{e.instance.destruct(),this.elements=this.elements.filter((t=>t!==e))}))}))}}if(void 0===window.Snowboard)throw new Error("Snowboard must be loaded in order to use the Backend UI.");(e=>{e.addPlugin("backend.ajax.handler",s),e.addPlugin("backend.ui.eventHandler",a),e.addPlugin("backend.ui.widgetHandler",o),e["backend.ajax.handler"]().addPrefilter(),window.AssetManager={load:(t,n)=>{e.assetLoader().load(t).then((()=>{n&&"function"==typeof n&&n()}))}},window.assetManager=window.AssetManager})(window.Snowboard),window.Vue=i}},function(e){e.O(0,[429],(function(){return t=286,e(e.s=t);var t}));e.O()}]); \ No newline at end of file +"use strict";(self.webpackChunk_wintercms_wn_backend_module=self.webpackChunk_wintercms_wn_backend_module||[]).push([[476],{385:function(e,t,n){var r=n(35),i=n(171);class s extends Snowboard.Singleton{listens(){return{ready:"ready",ajaxFetchOptions:"ajaxFetchOptions",ajaxUpdateComplete:"ajaxUpdateComplete"}}ready(){window.jQuery&&((0,i.M)("render"),document.addEventListener("$render",(()=>{this.snowboard.globalEvent("render")})),window.jQuery(document).trigger("render"))}addPrefilter(){window.jQuery&&window.jQuery.ajaxPrefilter((e=>{this.hasToken()&&(e.headers||(e.headers={}),e.headers["X-CSRF-TOKEN"]=this.getToken())}))}ajaxFetchOptions(e){this.hasToken()&&(e.headers["X-CSRF-TOKEN"]=this.getToken())}ajaxUpdateComplete(){window.jQuery&&window.jQuery(document).trigger("render")}hasToken(){const e=document.querySelector('meta[name="csrf-token"]');return!!e&&!!e.hasAttribute("content")}getToken(){return document.querySelector('meta[name="csrf-token"]').getAttribute("content")}}class a extends Snowboard.PluginBase{construct(e,t){if(e instanceof Snowboard.PluginBase==!1)throw new Error("Event handling can only be applied to Snowboard classes.");if(!t)throw new Error("Event prefix is required.");this.instance=e,this.eventPrefix=t,this.events=[]}on(e,t){this.events.push({event:e,callback:t})}off(e,t){this.events=this.events.filter((n=>n.event!==e||n.callback!==t))}once(e,t){var n=this;const r=this.events.push({event:e,callback:function(){t(...arguments),n.events.splice(r-1,1)}})}fire(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;rt.event===e));let s=!1;i.forEach((e=>{s||!1===e.callback(...n)&&(s=!0)})),s||this.snowboard.globalEvent(`${this.eventPrefix}.${e}`,...n)}firePromise(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;rt.event===e)),s=i.filter((e=>null!==e),i.map((e=>e.callback(...n))));Promise.all(s).then((()=>{this.snowboard.globalPromiseEvent(`${this.eventPrefix}.${e}`,...n)}))}}class o extends Snowboard.Singleton{construct(){this.changedElements=new Set}listens(){return{ready:"onReady",render:"setUpTriggers","trigger.action":"onTriggerAction"}}onReady(){(0,i.M)("oc.triggerOn.update"),(0,i.M)("change"),document.addEventListener("$change",(e=>{if(e.throughTrigger)return;const t=new InputEvent("change");t.throughTrigger=!0,e.target.dispatchEvent(t)})),this.setUpTriggers()}setUpTriggers(){Array.from(document.querySelectorAll("*")).filter((e=>[...e.attributes].filter((e=>{let{name:t}=e;return t.startsWith("data-trigger-")})).length>0)).forEach((e=>{const t=this.snowboard.trigger(e);e.addEventListener("$oc.triggerOn.update",(()=>{t.runEvents(e)}))}))}onTriggerAction(e,t,n,r){"show"!==n.name&&"hide"!==n.name||this.actionShow(n.parameters[0]?Array.from(e.querySelectorAll(n.parameters[0])):[e],"show"===n.name?r:!r)}actionShow(e,t){e.forEach((e=>{t&&e.classList.contains("hide")?e.classList.remove("hide"):t||e.classList.contains("hide")||e.classList.add("hide")}))}}class d extends Snowboard.Singleton{construct(){this.registeredWidgets=[],this.elements=[],this.events={mutate:e=>this.onMutation(e)},this.observer=null}listens(){return{ready:"onReady",render:"onRender",ajaxUpdate:"onAjaxUpdate"}}register(e,t,n){this.registeredWidgets.push({control:e,widget:t,callback:n})}unregister(e){this.registeredWidgets=this.registeredWidgets.filter((t=>t.control!==e))}onReady(){this.initializeWidgets(document.body),this.observer||(this.observer=new MutationObserver(this.events.mutate),this.observer.observe(document.body,{childList:!0,subtree:!0}))}onRender(){this.initializeWidgets(document.body)}onAjaxUpdate(e){this.initializeWidgets(e)}initializeWidgets(e){this.registeredWidgets.forEach((t=>{const n=e.querySelectorAll(`[data-control="${t.control}"]:not([data-widget-initialized])`);n.length&&n.forEach((e=>{if(e.dataset.widgetInitialized)return;const n=this.snowboard[t.widget](e);this.elements.push({element:e,instance:n}),e.dataset.widgetInitialized=!0,this.snowboard.globalEvent("backend.widget.initialized",e,n),"function"==typeof t.callback&&t.callback(n,e)}))}))}getWidget(e){const t=this.elements.find((t=>t.element===e));return t?t.instance:null}onMutation(e){const t=e.filter((e=>e.removedNodes.length)).map((e=>Array.from(e.removedNodes))).flat();t.length&&t.forEach((e=>{const t=this.elements.filter((t=>e.contains(t.element)));t.length&&t.forEach((e=>{e.instance.destruct(),this.elements=this.elements.filter((t=>t!==e))}))}))}}if(void 0===window.Snowboard)throw new Error("Snowboard must be loaded in order to use the Backend UI.");(e=>{e.addPlugin("backend.ajax.handler",s),e.addPlugin("backend.ui.eventHandler",a),e.addPlugin("backend.input.triggerHandler",o),e.addPlugin("backend.ui.widgetHandler",d),e["backend.ajax.handler"]().addPrefilter(),window.AssetManager={load:(t,n)=>{e.assetLoader().load(t).then((()=>{n&&"function"==typeof n&&n()}))}},window.assetManager=window.AssetManager})(window.Snowboard),window.Vue=r}},function(e){e.O(0,[429],(function(){return t=385,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/modules/backend/assets/ui/js/index.js b/modules/backend/assets/ui/js/index.js index cf4f3cad81..effffa0026 100644 --- a/modules/backend/assets/ui/js/index.js +++ b/modules/backend/assets/ui/js/index.js @@ -1,6 +1,7 @@ import * as Vue from 'vue'; import BackendAjaxHandler from './ajax/Handler'; import BackendUiEventHandler from './ui/EventHandler'; +import BackendInputTriggerHandler from './input/TriggerHandler'; import BackendUiWidgetHandler from './ui/WidgetHandler'; if (window.Snowboard === undefined) { @@ -10,6 +11,7 @@ if (window.Snowboard === undefined) { ((Snowboard) => { Snowboard.addPlugin('backend.ajax.handler', BackendAjaxHandler); Snowboard.addPlugin('backend.ui.eventHandler', BackendUiEventHandler); + Snowboard.addPlugin('backend.input.triggerHandler', BackendInputTriggerHandler); Snowboard.addPlugin('backend.ui.widgetHandler', BackendUiWidgetHandler); // Add the pre-filter immediately diff --git a/modules/backend/assets/ui/js/input/TriggerHandler.js b/modules/backend/assets/ui/js/input/TriggerHandler.js new file mode 100644 index 0000000000..155a5d068a --- /dev/null +++ b/modules/backend/assets/ui/js/input/TriggerHandler.js @@ -0,0 +1,89 @@ +import { delegate } from 'jquery-events-to-dom-events'; + +/** + * Backend trigger handler. + * + * Registers the usage of the new Trigger functionality, whilst mapping the old jQuery-style events + * to the new functionality. + * + * @copyright 2024 Winter. + * @author Ben Thomson + */ +export default class TriggerHandler extends Snowboard.Singleton { + construct() { + this.changedElements = new Set(); + } + + /** + * Listeners. + * + * @returns {Object} + */ + listens() { + return { + ready: 'onReady', + render: 'setUpTriggers', + 'trigger.action': 'onTriggerAction', + }; + } + + onReady() { + delegate('oc.triggerOn.update'); + + /** + * A number of widgets trigger a change event on a hidden element when they are updated, + * however, this change event is a jQuery "change" event, not the native DOM "change" event. + * + * The following intercepts the jQuery event and dispatches a native event as well. + */ + delegate('change'); + document.addEventListener('$change', (event) => { + if (event.throughTrigger) { + return; + } + + const newEvent = new InputEvent('change'); + newEvent.throughTrigger = true; + event.target.dispatchEvent(newEvent); + }); + + this.setUpTriggers(); + } + + setUpTriggers() { + // Scan for triggers + Array + .from(document.querySelectorAll('*')) + .filter( + (element) => [...element.attributes].filter( + ({ name }) => name.startsWith('data-trigger-'), + ).length > 0, + ).forEach((element) => { + const trigger = this.snowboard.trigger(element); + element.addEventListener('$oc.triggerOn.update', () => { + trigger.runEvents(element); + }); + }); + } + + onTriggerAction(element, trigger, action, conditionMet) { + if (action.name === 'show' || action.name === 'hide') { + this.actionShow( + (action.parameters[0]) + ? Array.from(element.querySelectorAll(action.parameters[0])) + : [element], + (action.name === 'show') ? conditionMet : !conditionMet, + ); + } + } + + actionShow(elements, show) { + elements.forEach((element) => { + if (show && element.classList.contains('hide')) { + element.classList.remove('hide'); + } else if (!show && !element.classList.contains('hide')) { + element.classList.add('hide'); + } + }); + } +} diff --git a/modules/backend/formwidgets/codeeditor/assets/js/build-min.js b/modules/backend/formwidgets/codeeditor/assets/js/build-min.js index e1dd79a93e..4a6c376976 100644 --- a/modules/backend/formwidgets/codeeditor/assets/js/build-min.js +++ b/modules/backend/formwidgets/codeeditor/assets/js/build-min.js @@ -1290,9 +1290,9 @@ getData=function(row){return popup.data[row];};popup.getRow=function(){return se z-index: 2;\ }\ .ace_editor.ace_autocomplete .ace_scroller {\ - background: none;\ - border: none;\ - box-shadow: none;\ + background: none;\ + border: none;\ + box-shadow: none;\ }\ .ace_rightAlignedText {\ color: gray;\ diff --git a/modules/backend/widgets/mediamanager/assets/js/mediamanager-browser-min.js b/modules/backend/widgets/mediamanager/assets/js/mediamanager-browser-min.js index 78f74226c7..9ff766b4fe 100644 --- a/modules/backend/widgets/mediamanager/assets/js/mediamanager-browser-min.js +++ b/modules/backend/widgets/mediamanager/assets/js/mediamanager-browser-min.js @@ -540,4 +540,4 @@ case'undo-resizing':this.undoResizing() break}} MediaManagerImageCropPopup.prototype.onSelectionChanged=function(c){this.updateSelectionSizeLabel(c.w,c.h)} MediaManagerImageCropPopup.DEFAULTS={alias:undefined,onDone:undefined} -$.wn.mediaManager.imageCropPopup=MediaManagerImageCropPopup}(window.jQuery); +$.wn.mediaManager.imageCropPopup=MediaManagerImageCropPopup}(window.jQuery); \ No newline at end of file diff --git a/modules/system/assets/js/build/system.debug.js b/modules/system/assets/js/build/system.debug.js index 147b45fcc0..e238f3ac3e 100644 --- a/modules/system/assets/js/build/system.debug.js +++ b/modules/system/assets/js/build/system.debug.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_wintercms_wn_system_module=self.webpackChunk_wintercms_wn_system_module||[]).push([[639,38,813],{660:function(e,t,s){s.d(t,{A:function(){return n}});class n{constructor(e){this.snowboard=e}construct(){}dependencies(){return[]}listens(){return{}}destruct(){this.detach(),delete this.snowboard}destructor(){this.destruct()}}},373:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{}},477:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{listens(){return{ajaxLoadAssets:"load"}}dependencies(){return["url"]}async load(e){if(e.js&&e.js.length>0)for(const t of e.js)try{await this.loadScript(t)}catch(e){return Promise.reject(e)}if(e.css&&e.css.length>0)for(const t of e.css)try{await this.loadStyle(t)}catch(e){return Promise.reject(e)}if(e.img&&e.img.length>0)for(const t of e.img)try{await this.loadImage(t)}catch(e){return Promise.reject(e)}return Promise.resolve()}loadScript(e){return new Promise(((t,s)=>{e=this.snowboard.url().asset(e);if(document.querySelector(`script[src="${e}"]`))return void t();const n=document.createElement("script");n.setAttribute("type","text/javascript"),n.setAttribute("src",e),n.addEventListener("load",(()=>{this.snowboard.globalEvent("assetLoader.loaded","script",e,n),t()})),n.addEventListener("error",(()=>{this.snowboard.globalEvent("assetLoader.error","script",e,n),s(new Error(`Unable to load script file: "${e}"`))})),document.body.append(n)}))}loadStyle(e){return new Promise(((t,s)=>{e=this.snowboard.url().asset(e);if(document.querySelector(`link[rel="stylesheet"][href="${e}"]`))return void t();const n=document.createElement("link");n.setAttribute("rel","stylesheet"),n.setAttribute("href",e),n.addEventListener("load",(()=>{this.snowboard.globalEvent("assetLoader.loaded","style",e,n),t()})),n.addEventListener("error",(()=>{this.snowboard.globalEvent("assetLoader.error","style",e,n),s(new Error(`Unable to load stylesheet file: "${e}"`))})),document.head.append(n)}))}loadImage(e){return new Promise(((t,s)=>{e=this.snowboard.url().asset(e);const n=new Image;n.addEventListener("load",(()=>{this.snowboard.globalEvent("assetLoader.loaded","image",e,n),t()})),n.addEventListener("error",(()=>{this.snowboard.globalEvent("assetLoader.error","image",e,n),s(new Error(`Unable to load image file: "${e}"`))})),n.src=e}))}}},293:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{dependencies(){return["request"]}listens(){return{ajaxStart:"ajaxStart",ajaxDone:"ajaxDone"}}ajaxStart(e,t){if(t.element)if("FORM"===t.element.tagName){const e=t.element.querySelectorAll("[data-attach-loading]");e.length>0&&e.forEach((e=>{e.classList.add(this.getLoadingClass(e))}))}else void 0!==t.element.dataset.attachLoading&&t.element.classList.add(this.getLoadingClass(t.element))}ajaxDone(e,t){if(t.element)if("FORM"===t.element.tagName){const e=t.element.querySelectorAll("[data-attach-loading]");e.length>0&&e.forEach((e=>{e.classList.remove(this.getLoadingClass(e))}))}else void 0!==t.element.dataset.attachLoading&&t.element.classList.remove(this.getLoadingClass(t.element))}getLoadingClass(e){return void 0!==e.dataset.attachLoading&&""!==e.dataset.attachLoading?e.dataset.attachLoading:"wn-loading"}}},490:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{construct(e,t,s){if(e instanceof n.A==!1)throw new Error("You must provide a Snowboard plugin to enable data configuration");if(t instanceof HTMLElement==!1)throw new Error("Data configuration can only be extracted from HTML elements");this.instance=e,this.element=t,this.localConfig=s||{},this.instanceConfig={},this.acceptedConfigs={},this.refresh()}get(e){return void 0===e?this.instanceConfig:void 0!==this.instanceConfig[e]?this.instanceConfig[e]:void 0}set(e,t,s){if(void 0===e)throw new Error("You must provide a configuration key to set");this.instanceConfig[e]=t,!0===s&&(this.element.dataset[e]=t,this.localConfig[e]=t)}refresh(){this.acceptedConfigs=this.getAcceptedConfigs(),this.instanceConfig=this.processConfig()}getAcceptedConfigs(){return void 0!==this.instance.acceptAllDataConfigs&&!0===this.instance.acceptAllDataConfigs||void 0!==this.instance.defaults&&"function"==typeof this.instance.defaults&&"object"==typeof this.instance.defaults()&&Object.keys(this.instance.defaults())}getDefaults(){return void 0!==this.instance.defaults&&"function"==typeof this.instance.defaults&&"object"==typeof this.instance.defaults()?this.instance.defaults():{}}processConfig(){const e=this.getDefaults();if(!1===this.acceptedConfigs)return e;for(const t in this.element.dataset)(!0===this.acceptedConfigs||this.acceptedConfigs.includes(t))&&(e[t]=this.coerceValue(this.element.dataset[t]));for(const t in this.localConfig)(!0===this.acceptedConfigs||this.acceptedConfigs.includes(t))&&(e[t]=this.localConfig[t]);return e}coerceValue(e){const t=String(e);if("null"===t)return null;if("undefined"!==t){if(t.startsWith("base64:")){const e=t.replace(/^base64:/,""),s=atob(e);return this.coerceValue(s)}if(["true","yes"].includes(t.toLowerCase()))return!0;if(["false","no"].includes(t.toLowerCase()))return!1;if(/^[-+]?[0-9]+(\.[0-9]+)?$/.test(t))return Number(t);try{return this.snowboard.jsonParser().parse(t)}catch(e){return""===t||t}}}}},336:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{construct(e,t,s){if(this.message=e,this.type=t||"default",this.duration=Number(s||7),this.duration<0)throw new Error("Flash duration must be a positive number, or zero");this.clear(),this.timer=null,this.flashTimer=null,this.create()}dependencies(){return["transition"]}destruct(){null!==this.timer&&window.clearTimeout(this.timer),this.flashTimer&&this.flashTimer.remove(),this.flash&&(this.flash.remove(),this.flash=null,this.flashTimer=null),super.destruct()}create(){this.snowboard.globalEvent("flash.create",this),this.flash=document.createElement("DIV"),this.flash.innerHTML=this.message,this.flash.classList.add("flash-message",this.type),this.flash.removeAttribute("data-control"),this.flash.addEventListener("click",(()=>this.remove())),this.flash.addEventListener("mouseover",(()=>this.stopTimer())),this.flash.addEventListener("mouseout",(()=>this.startTimer())),this.duration>0?(this.flashTimer=document.createElement("DIV"),this.flashTimer.classList.add("flash-timer"),this.flash.appendChild(this.flashTimer)):this.flash.classList.add("no-timer"),document.body.appendChild(this.flash),this.snowboard.transition(this.flash,"show",(()=>{this.startTimer()}))}remove(){this.snowboard.globalEvent("flash.remove",this),this.stopTimer(),this.snowboard.transition(this.flash,"hide",(()=>{this.flash.remove(),this.flash=null,this.destruct()}))}clear(){document.querySelectorAll("body > div.flash-message").forEach((e=>e.remove()))}startTimer(){0!==this.duration&&(this.timerTrans=this.snowboard.transition(this.flashTimer,"timeout",null,`${this.duration}.0s`,!0),this.timer=window.setTimeout((()=>this.remove()),1e3*this.duration))}stopTimer(){this.timerTrans&&this.timerTrans.cancel(),this.timer&&window.clearTimeout(this.timer)}}},758:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{dependencies(){return["request"]}listens(){return{ready:"ready",ajaxStart:"ajaxStart"}}ready(){this.counter=0,this.createStripe()}ajaxStart(e,t){!1!==t.options.stripe&&(this.show(),e.then((()=>{this.hide()})).catch((()=>{this.hide()})))}createStripe(){this.indicator=document.createElement("DIV"),this.stripe=document.createElement("DIV"),this.stripeLoaded=document.createElement("DIV"),this.indicator.classList.add("stripe-loading-indicator","loaded"),this.stripe.classList.add("stripe"),this.stripeLoaded.classList.add("stripe-loaded"),this.indicator.appendChild(this.stripe),this.indicator.appendChild(this.stripeLoaded),document.body.appendChild(this.indicator)}show(){this.counter+=1;const e=this.stripe.cloneNode(!0);this.indicator.appendChild(e),this.stripe.remove(),this.stripe=e,this.counter>1||(this.indicator.classList.remove("loaded"),document.body.classList.add("wn-loading"))}hide(e){this.counter-=1,!0===e&&(this.counter=0),this.counter<=0&&(this.indicator.classList.add("loaded"),document.body.classList.remove("wn-loading"))}}},75:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{listens(){return{ready:"ready"}}ready(){let e=!1;if(document.querySelectorAll('link[rel="stylesheet"]').forEach((t=>{t.href.endsWith("/modules/system/assets/css/snowboard.extras.css")&&(e=!0)})),!e){const e=document.createElement("link");e.setAttribute("rel","stylesheet"),e.setAttribute("href",this.snowboard.url().asset("/modules/system/assets/css/snowboard.extras.css")),document.head.appendChild(e)}}}},843:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{construct(e,t,s,n,i){if(e instanceof HTMLElement==!1)throw new Error("A HTMLElement must be provided for transitioning");if(this.element=e,"string"!=typeof t)throw new Error("Transition name must be specified as a string");if(this.transition=t,s&&"function"!=typeof s)throw new Error("Callback must be a valid function");this.callback=s,this.duration=n?this.parseDuration(n):null,this.trailTo=!0===i,this.doTransition()}eventClasses(){for(var e=arguments.length,t=new Array(e),s=0;s{const[s,n]=e;-1!==t.indexOf(s)&&i.push(n)})),i}doTransition(){null!==this.duration&&(this.element.style.transitionDuration=this.duration),this.resetClasses(),this.eventClasses("in","active").forEach((e=>{this.element.classList.add(e)})),window.requestAnimationFrame((()=>{"0s"!==window.getComputedStyle(this.element)["transition-duration"]?(this.element.addEventListener("transitionend",(()=>this.onTransitionEnd()),{once:!0}),window.requestAnimationFrame((()=>{this.element.classList.remove(this.eventClasses("in")[0]),this.element.classList.add(this.eventClasses("out")[0])}))):(this.resetClasses(),this.callback&&this.callback.apply(this.element),this.destruct())}))}onTransitionEnd(){this.eventClasses("active",this.trailTo?"":"out").forEach((e=>{this.element.classList.remove(e)})),this.callback&&this.callback.apply(this.element),null!==this.duration&&(this.element.style.transitionDuration=null),this.destruct()}cancel(){this.element.removeEventListener("transitionend",(()=>this.onTransitionEnd),{once:!0}),this.resetClasses(),null!==this.duration&&(this.element.style.transitionDuration=null),this.destruct()}resetClasses(){this.eventClasses().forEach((e=>{this.element.classList.remove(e)}))}parseDuration(e){const t=/^([0-9]+(\.[0-9]+)?)(m?s)?$/.exec(e),s=Number(t[1]);return"sec"===("s"===t[3]?"sec":"msec")?1e3*s+"ms":`${Math.floor(s)}ms`}}},54:function(e,t){t.A={get(e,t,s){if("string"==typeof t){const s=t.toLowerCase();if(e.hasPlugin(s))return function(){return Reflect.get(e,"plugins")[s].getInstance(...arguments)}}return Reflect.get(e,t,s)},has(e,t){if("string"==typeof t){const s=t.toLowerCase();if(e.hasPlugin(s))return!0}return Reflect.has(e,t)}}},160:function(e,t,s){s.d(t,{A:function(){return g}});var n=s(660),i=s(373),r={get(e,t,s){if("string"==typeof t){const s=t.toLowerCase();if(["attachAbstracts","loadUtilities","initialise","initialiseSingletons"].includes(t))throw new Error(`You cannot use the "${t}" Snowboard method within a plugin.`);if(e.hasPlugin(s))return function(){return Reflect.get(e,"plugins")[s].getInstance(...arguments)}}return Reflect.get(e,t,s)},has(e,t){if("string"==typeof t){const s=t.toLowerCase();if(["attachAbstracts","loadUtilities","initialise","initialiseSingletons"].includes(t))return!1;if(e.hasPlugin(s))return!0}return Reflect.has(e,t)}};class o{constructor(e,t,s){this.name=e,this.snowboard=new Proxy(t,r),this.instance=s,Object.freeze(this.instance),this.instances=[],this.singleton={initialised:!1},Object.seal(this.singleton),this.mocks={},this.originalFunctions={},Object.freeze(o.prototype),Object.freeze(this)}hasMethod(e){return!this.isFunction()&&"function"==typeof this.instance.prototype[e]}callMethod(){if(this.isFunction())return null;for(var e=arguments.length,t=new Array(e),s=0;s!this.snowboard.getPluginNames().includes(e)));throw new Error(`The "${this.name}" plugin requires the following plugins: ${e.join(", ")}`)}if(this.isSingleton())return 0===this.instances.length&&this.initialiseSingleton(...s),Object.keys(this.mocks).length>0&&(Object.entries(this.originalFunctions).forEach((e=>{const[t,s]=e;this.instances[0][t]=s})),Object.entries(this.mocks).forEach((t=>{const[s,n]=t;this.instances[0][s]=function(){for(var t=arguments.length,s=new Array(t),i=0;i0&&(Object.entries(this.originalFunctions).forEach((e=>{const[t,s]=e;this.instance.prototype[t]=s})),Object.entries(this.mocks).forEach((t=>{const[s,n]=t;this.instance.prototype[s]=function(){for(var t=arguments.length,s=new Array(t),i=0;ithis.instances.splice(this.instances.indexOf(i),1),i.construct(...s),this.instances.push(i),i}getInstances(){return this.isFunction()?[]:this.instances}isFunction(){return"function"==typeof this.instance&&this.instance.prototype instanceof n.A==!1}isSingleton(){return this.instance.prototype instanceof i.A==!0}isInitialised(){return!this.isSingleton()||this.singleton.initialised}initialiseSingleton(){if(!this.isSingleton())return;for(var e=arguments.length,t=new Array(e),s=0;sthis.instances.splice(this.instances.indexOf(n),1),n.construct(...t),this.instances.push(n),this.singleton.initialised=!0}getDependencies(){return this.isFunction()||"function"!=typeof this.instance.prototype.dependencies?[]:this.instance.prototype.dependencies().map((e=>e.toLowerCase()))}dependenciesFulfilled(){const e=this.getDependencies();let t=!0;return e.forEach((e=>{this.snowboard.hasPlugin(e)||(t=!1)})),t}mock(e,t){var s=this;if(!this.isFunction()){if(!this.instance.prototype[e])throw new Error(`Function "${e}" does not exist and cannot be mocked`);this.mocks[e]=t,this.originalFunctions[e]=this.instance.prototype[e],this.isSingleton()&&0===this.instances.length&&(this.initialiseSingleton(),this.instances[0][e]=function(){for(var e=arguments.length,n=new Array(e),i=0;i{const[t,s]=e;void 0!==this.defaults[t]&&(this.defaults[t]=s)}))}getDefaults(){const e={};return Object.entries(this.defaults).forEach((t=>{const[s,n]=t;null!==this.defaults[s]&&(e[s]=n)})),e}get(e){if(void 0===e){const e=a.A.get();return Object.entries(e).forEach((t=>{const[s,n]=t;this.snowboard.globalEvent("cookie.get",s,n,(t=>{e[s]=t}))})),e}let t=a.A.get(e);return this.snowboard.globalEvent("cookie.get",e,t,(e=>{t=e})),t}set(e,t,s){let n=t;return this.snowboard.globalEvent("cookie.set",e,t,(e=>{n=e})),a.A.set(e,n,h(h({},this.getDefaults()),s))}remove(e,t){a.A.remove(e,h(h({},this.getDefaults()),t))}}class u extends i.A{construct(){window.wnJSON=e=>this.parse(e),window.ocJSON=window.wnJSON}parse(e){const t=this.parseString(e);return JSON.parse(t)}parseString(e){let t=e.trim();if(!t.length)throw new Error("Broken JSON object.");let s="",n=null,i=null,r="";for(;t&&","===t[0];)t=t.substr(1);if('"'===t[0]||"'"===t[0]){if(t[t.length-1]!==t[0])throw new Error("Invalid string JSON object.");r='"';for(let e=1;e="0"&&e[t]<="9"){s="";for(let n=t;n="0"&&e[n]<="9"))return{originLength:s.length,body:s};s+=e[n]}throw new Error(`Broken JSON number body near ${s}`)}if("{"===e[t]||"["===e[t]){const n=[e[t]];s=e[t];for(let i=t+1;i=0?t-5:0,50)}`)}parseKey(e,t,s){let n="";for(let i=t;i="a"&&e[0]<="z"||e[0]>="A"&&e[0]<="Z"||"_"===e[0]||(e[0]>="0"&&e[0]<="9"||("$"===e[0]||e.charCodeAt(0)>255)))}isBlankChar(e){return" "===e||"\n"===e||"\t"===e}}class f extends i.A{construct(){window.wnSanitize=e=>this.sanitize(e),window.ocSanitize=window.wnSanitize}sanitize(e,t){const s=(new DOMParser).parseFromString(e,"text/html"),n=void 0===t||"boolean"!=typeof t||t;return this.sanitizeNode(s.getRootNode()),n?s.body.innerHTML:s.innerHTML}sanitizeNode(e){if("SCRIPT"===e.tagName)return void e.remove();this.trimAttributes(e);Array.from(e.children).forEach((e=>{this.sanitizeNode(e)}))}trimAttributes(e){if(e.attributes)for(let t=0;t{this.autoInitSingletons&&this.initialiseSingletons(),this.globalEvent("ready"),this.readiness.dom=!0}))}initialiseSingletons(){Object.values(this.plugins).forEach((e=>{e.isSingleton()&&e.dependenciesFulfilled()&&e.initialiseSingleton()}))}addPlugin(e,t){const s=e.toLowerCase();if(this.hasPlugin(s))throw new Error(`A plugin called "${e}" is already registered.`);if("function"!=typeof t&&t instanceof n.A==!1)throw new Error("The provided plugin must extend the PluginBase class, or must be a callback function.");if(void 0!==this[e]||void 0!==this[s])throw new Error("The given name is already in use for a property or method of the Snowboard class.");this.plugins[s]=new o(s,this,t),this.debug(`Plugin "${e}" registered`),Object.values(this.getPlugins()).forEach((e=>{if(e.isSingleton()&&!e.isInitialised()&&e.dependenciesFulfilled()&&e.hasMethod("listens")&&Object.keys(e.callMethod("listens")).includes("ready")&&this.readiness.dom){const t=e.callMethod("listens").ready;e.callMethod(t)}}))}removePlugin(e){const t=e.toLowerCase();this.hasPlugin(t)?(this.plugins[t].getInstances().forEach((e=>{e.destruct()})),delete this.plugins[t],delete this[t],delete this[e],this.debug(`Plugin "${e}" removed`)):this.debug(`Plugin "${e}" already removed`)}hasPlugin(e){const t=e.toLowerCase();return void 0!==this.plugins[t]}getPlugins(){return this.plugins}getPluginNames(){return Object.keys(this.plugins)}getPlugin(e){const t=e.toLowerCase();if(!this.hasPlugin(t))throw new Error(`No plugin called "${t}" has been registered.`);return this.plugins[t]}listensToEvent(e){const t=[];return Object.entries(this.plugins).forEach((s=>{const[n,i]=s;if(i.isFunction())return;if(!i.dependenciesFulfilled())return;if(!i.hasMethod("listens"))return;const r=i.callMethod("listens");"string"!=typeof r[e]&&"function"!=typeof r[e]||t.push(n)})),t}ready(e){this.readiness.dom&&e(),this.on("ready",e)}on(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].includes(t)||this.listeners[e].push(t)}off(e,t){if(!this.listeners[e])return;const s=this.listeners[e].indexOf(t);-1!==s&&this.listeners[e].splice(s,1)}globalEvent(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n{const n=this.getPlugin(t);if(n.isFunction())return;n.isSingleton()&&0===n.getInstances().length&&n.initialiseSingleton();const i=n.callMethod("listens")[e];n.getInstances().forEach((n=>{if(!r)if("function"==typeof i)try{!1===i.apply(n,s)&&(r=!0)}catch(s){this.error(`Error thrown in "${e}" event by "${t}" plugin.`,s)}else if("string"==typeof i){if(!n[i])throw new Error(`Missing "${i}" method in "${t}" plugin`);try{!1===n[i](...s)&&(r=!0,this.debug(`Global event "${e}" cancelled by "${t}" plugin`))}catch(s){this.error(`Error thrown in "${e}" event by "${t}" plugin.`,s)}}else this.error(`Listen method for "${e}" event in "${t}" plugin is not a function or string.`)}))})),!r&&this.listeners[e]&&this.listeners[e].length>0&&(this.debug(`Found ${this.listeners[e].length} ad-hoc listener(s) for global event "${e}"`),this.listeners[e].forEach((t=>{if(!r)try{!1===t(...s)&&(r=!0,this.debug(`Global event "${e} cancelled by an ad-hoc listener.`))}catch(t){this.error(`Error thrown in "${e}" event by an ad-hoc listener.`,t)}}))),!r}globalPromiseEvent(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n{const n=this.getPlugin(t);if(n.isFunction())return;n.isSingleton()&&0===n.getInstances().length&&n.initialiseSingleton();const i=n.callMethod("listens")[e];n.getInstances().forEach((n=>{if("function"==typeof i)try{const e=i.apply(n,s);if(e instanceof Promise==!1)return;r.push(e)}catch(s){this.error(`Error thrown in "${e}" event by "${t}" plugin.`,s)}else if("string"==typeof i){if(!n[i])throw new Error(`Missing "${i}" method in "${t}" plugin`);try{const e=n[i](...s);if(e instanceof Promise==!1)return;r.push(e)}catch(s){this.error(`Error thrown in "${e}" promise event by "${t}" plugin.`,s)}}else this.error(`Listen method for "${e}" event in "${t}" plugin is not a function or string.`)}))})),this.listeners[e]&&this.listeners[e].length>0&&(this.debug(`Found ${this.listeners[e].length} ad-hoc listener(s) for global promise event "${e}"`),this.listeners[e].forEach((t=>{try{const e=t(...s);if(e instanceof Promise==!1)return;r.push(e)}catch(t){this.error(`Error thrown in "${e}" promise event by an ad-hoc listener.`,t)}}))),0===r.length?Promise.resolve():Promise.all(r)}logMessage(e,t,s){console.groupCollapsed("%c[Snowboard]",`color: ${e}; font-weight: ${t?"bold":"normal"};`,s);for(var n=arguments.length,i=new Array(n>3?n-3:0),r=3;r{e+=1,console.log(`%c${e}:`,"color: rgb(88, 88, 88); font-weight: normal;",t)})),console.groupEnd(),console.groupCollapsed("%cTrace","color: rgb(45, 167, 199); font-weight: bold;"),console.trace(),console.groupEnd()}else console.trace();console.groupEnd()}log(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n1?t-1:0),n=1;n1?t-1:0),n=1;n{const t=new Proxy(new n.A(!0,!0),i.A);e.snowboard=t,e.Snowboard=t,e.SnowBoard=t})(window)},59:function(e,t,s){var n=s(660);function i(e,t){var s=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),s.push.apply(s,n)}return s}function r(e){for(var t=1;t{e&&this.doAjax().then((e=>{if(e.cancelled)return this.cancelled=!0,void this.complete();this.responseData=e,this.processUpdate(e).then((()=>{!1===e.X_WINTER_SUCCESS?this.processError(e):this.processResponse(e)}))}),(e=>{this.responseError=e,this.processError(e)}))})):this.doAjax().then((e=>{if(e.cancelled)return this.cancelled=!0,void this.complete();this.responseData=e,this.processUpdate(e).then((()=>{!1===e.X_WINTER_SUCCESS?this.processError(e):this.processResponse(e)}))}),(e=>{this.responseError=e,this.processError(e)})):this.cancelled=!0}else this.cancelled=!0}dependencies(){return["cookie","jsonParser"]}checkRequest(){if(this.element&&this.element instanceof Element==!1)throw new Error("The element provided must be an Element instance");if(void 0===this.handler)throw new Error("The AJAX handler name is not specified.");if(!this.isHandlerName(this.handler))throw new Error('Invalid AJAX handler name. The correct handler name format is: "onEvent".')}getFetch(){return this.fetchOptions=void 0!==this.options.fetchOptions&&"object"==typeof this.options.fetchOptions?this.options.fetchOptions:{method:"POST",headers:this.headers,body:this.data,redirect:"follow",mode:"same-origin"},this.snowboard.globalEvent("ajaxFetchOptions",this.fetchOptions,this),fetch(this.url,this.fetchOptions)}doClientValidation(){return!0!==this.options.browserValidate||!this.form||!1!==this.form.checkValidity()||(this.form.reportValidity(),!1)}doAjax(){if(!1===this.snowboard.globalEvent("ajaxBeforeSend",this))return Promise.resolve({cancelled:!0});const e=new Promise(((e,t)=>{this.getFetch().then((s=>{s.ok||406===s.status?s.headers.has("Content-Type")&&s.headers.get("Content-Type").includes("/json")?s.json().then((t=>{e(r(r({},t),{},{X_WINTER_SUCCESS:406!==s.status,X_WINTER_RESPONSE_CODE:s.status}))}),(e=>{t(this.renderError(`Unable to parse JSON response: ${e}`))})):s.text().then((t=>{e(t)}),(e=>{t(this.renderError(`Unable to process response: ${e}`))})):s.headers.has("Content-Type")&&s.headers.get("Content-Type").includes("/json")?s.json().then((e=>{e.message&&e.exception?t(this.renderError(e.message,e.exception,e.file,e.line,e.trace)):t(e)}),(e=>{t(this.renderError(`Unable to parse JSON response: ${e}`))})):s.text().then((e=>{t(this.renderError(e))}),(e=>{t(this.renderError(`Unable to process response: ${e}`))}))}),(e=>{t(this.renderError(`Unable to retrieve a response from the server: ${e}`))}))}));if(this.snowboard.globalEvent("ajaxStart",e,this),this.element){const t=new Event("ajaxPromise");t.promise=e,this.element.dispatchEvent(t)}return e}processUpdate(e){return new Promise(((t,s)=>{if("function"==typeof this.options.beforeUpdate&&!1===this.options.beforeUpdate.apply(this,[e]))return void t();const n={};if(Object.entries(e).forEach((e=>{const[t,s]=e;"X_WINTER"!==t.substr(0,8)&&(n[t]=s)})),0===Object.keys(n).length)return void(e.X_WINTER_ASSETS?this.processAssets(e.X_WINTER_ASSETS).then((()=>{t()}),(()=>{s()})):t());this.snowboard.globalPromiseEvent("ajaxBeforeUpdate",e,this).then((async()=>{e.X_WINTER_ASSETS&&await this.processAssets(e.X_WINTER_ASSETS),this.doUpdate(n).then((()=>{window.requestAnimationFrame((()=>t()))}),(()=>{s()}))}),(()=>{t()}))}))}doUpdate(e){return new Promise((t=>{const s=[];Object.entries(e).forEach((e=>{const[t,n]=e;let i=this.options.update&&this.options.update[t]?this.options.update[t]:t,r="replace";"@"===i.substr(0,1)?(r="append",i=i.substr(1)):"^"===i.substr(0,1)?(r="prepend",i=i.substr(1)):"#"!==i.substr(0,1)&&"."!==i.substr(0,1)&&(r="noop");const o=document.querySelectorAll(i);o.length>0&&o.forEach((e=>{switch(r){case"append":e.innerHTML+=n;break;case"prepend":e.innerHTML=n+e.innerHTML;break;case"noop":break;default:e.innerHTML=n}s.push(e),this.snowboard.globalEvent("ajaxUpdate",e,n,this);const t=new Event("ajaxUpdate");t.content=n,e.dispatchEvent(t)}))})),this.snowboard.globalEvent("ajaxUpdateComplete",s,this),t()}))}processResponse(e){if((!this.options.success||"function"!=typeof this.options.success||!1!==this.options.success(this.responseData,this))&&!1!==this.snowboard.globalEvent("ajaxSuccess",this.responseData,this)){if(this.element){const e=new Event("ajaxDone",{cancelable:!0});if(e.responseData=this.responseData,e.request=this,this.element.dispatchEvent(e),e.defaultPrevented)return}this.flash&&e.X_WINTER_FLASH_MESSAGES&&this.processFlashMessages(e.X_WINTER_FLASH_MESSAGES),this.redirect||e.X_WINTER_REDIRECT?this.processRedirect(this.redirect||e.X_WINTER_REDIRECT):this.complete()}}processError(e){if((!this.options.error||"function"!=typeof this.options.error||!1!==this.options.error(this.responseError,this))&&!1!==this.snowboard.globalEvent("ajaxError",this.responseError,this)){if(this.element){const e=new Event("ajaxFail",{cancelable:!0});if(e.responseError=this.responseError,e.request=this,this.element.dispatchEvent(e),e.defaultPrevented)return}if(e instanceof Error)this.processErrorMessage(e.message);else{let t=!1;e.X_WINTER_ERROR_FIELDS&&(t=this.processValidationErrors(e.X_WINTER_ERROR_FIELDS)),e.X_WINTER_ERROR_MESSAGE&&!t&&this.processErrorMessage(e.X_WINTER_ERROR_MESSAGE)}this.complete()}}processRedirect(e){"function"==typeof this.options.handleRedirectResponse&&!1===this.options.handleRedirectResponse.apply(this,[e])||!1!==this.snowboard.globalEvent("ajaxRedirect",e,this)&&(window.addEventListener("popstate",(()=>{if(this.element){const e=document.createEvent("CustomEvent");e.eventName="ajaxRedirected",this.element.dispatchEvent(e)}}),{once:!0}),window.location.assign(e))}processErrorMessage(e){"function"==typeof this.options.handleErrorMessage&&!1===this.options.handleErrorMessage.apply(this,[e])||!1!==this.snowboard.globalEvent("ajaxErrorMessage",e,this)&&window.alert(e)}processFlashMessages(e){"function"==typeof this.options.handleFlashMessages&&!1===this.options.handleFlashMessages.apply(this,[e])||this.snowboard.globalEvent("ajaxFlashMessages",e,this)}processValidationErrors(e){return"function"==typeof this.options.handleValidationErrors&&!1===this.options.handleValidationErrors.apply(this,[this.form,e])||!1===this.snowboard.globalEvent("ajaxValidationErrors",this.form,e,this)}processAssets(e){return this.snowboard.globalPromiseEvent("ajaxLoadAssets",e)}async doConfirm(){if("function"==typeof this.options.handleConfirmMessage)return!1!==this.options.handleConfirmMessage.apply(this,[this.confirm]);if(0===this.snowboard.listensToEvent("ajaxConfirmMessage").length)return window.confirm(this.confirm);const e=this.snowboard.globalPromiseEvent("ajaxConfirmMessage",this.confirm,this);try{if(await e)return!0}catch(e){return!1}return!1}complete(){if(this.options.complete&&"function"==typeof this.options.complete&&this.options.complete(this.responseData,this),this.snowboard.globalEvent("ajaxDone",this.responseData,this),this.element){const e=new Event("ajaxAlways");e.request=this,e.responseData=this.responseData,e.responseError=this.responseError,this.element.dispatchEvent(e)}this.destruct()}get form(){return this.options.form?"string"==typeof this.options.form?document.querySelector(this.options.form):this.options.form:this.element?"FORM"===this.element.tagName?this.element:this.element.closest("form"):null}get context(){return{handler:this.handler,options:this.options}}get headers(){const e={"X-Requested-With":"XMLHttpRequest","X-WINTER-REQUEST-HANDLER":this.handler,"X-WINTER-REQUEST-PARTIALS":this.extractPartials(this.options.update||[])};return this.flash&&(e["X-WINTER-REQUEST-FLASH"]=1),this.xsrfToken&&(e["X-XSRF-TOKEN"]=this.xsrfToken),e}get loading(){return this.options.loading||!1}get url(){return this.options.url||window.location.href}get redirect(){return this.options.redirect&&this.options.redirect.length?this.options.redirect:null}get flash(){return this.options.flash||!1}get files(){return!0===this.options.files&&(void 0!==FormData||(this.snowboard.debug("This browser does not support file uploads"),!1))}get xsrfToken(){return this.snowboard.cookie().get("XSRF-TOKEN")}get data(){const e="object"==typeof this.options.data?this.options.data:{},t=new FormData(this.form||void 0);return Object.keys(e).length>0&&this.createFormData(t,e),t}createFormData(e,t){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";"object"==typeof t?Array.isArray(t)&&""!==s?t.forEach((t=>{this.createFormData(e,t,`${s}[]`)})):Object.entries(t).forEach((t=>{const[n,i]=t;this.createFormData(e,i,""!==s?`${s}[${n}]`:n)})):e.append(s,t)}get confirm(){return this.options.confirm||!1}extractPartials(e){return Object.keys(e).join("&")}renderError(e,t,s,n,i){const r=new Error(e);return r.exception=t||null,r.file=s||null,r.line=n||null,r.trace=i||[],r}isHandlerName(e){return/^(?:\w+:{2})?on[A-Z0-9]/.test(e)}}if(void 0===window.Snowboard)throw new Error("Snowboard must be loaded in order to use the Javascript AJAX request feature.");window.Snowboard.addPlugin("request",a)}},function(e){var t=function(t){return e(e.s=t)};e.O(0,[969],(function(){return t(799),t(59),t(590)}));e.O()}]); \ No newline at end of file +"use strict";(self.webpackChunk_wintercms_wn_system_module=self.webpackChunk_wintercms_wn_system_module||[]).push([[639,38,813],{660:function(e,t,s){s.d(t,{A:function(){return n}});class n{constructor(e){this.snowboard=e}construct(){}dependencies(){return[]}listens(){return{}}destruct(){this.detach(),delete this.snowboard}destructor(){this.destruct()}}},373:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{}},477:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{listens(){return{ajaxLoadAssets:"load"}}dependencies(){return["url"]}async load(e){if(e.js&&e.js.length>0)for(const t of e.js)try{await this.loadScript(t)}catch(e){return Promise.reject(e)}if(e.css&&e.css.length>0)for(const t of e.css)try{await this.loadStyle(t)}catch(e){return Promise.reject(e)}if(e.img&&e.img.length>0)for(const t of e.img)try{await this.loadImage(t)}catch(e){return Promise.reject(e)}return Promise.resolve()}loadScript(e){return new Promise(((t,s)=>{e=this.snowboard.url().asset(e);if(document.querySelector(`script[src="${e}"]`))return void t();const n=document.createElement("script");n.setAttribute("type","text/javascript"),n.setAttribute("src",e),n.addEventListener("load",(()=>{this.snowboard.globalEvent("assetLoader.loaded","script",e,n),t()})),n.addEventListener("error",(()=>{this.snowboard.globalEvent("assetLoader.error","script",e,n),s(new Error(`Unable to load script file: "${e}"`))})),document.body.append(n)}))}loadStyle(e){return new Promise(((t,s)=>{e=this.snowboard.url().asset(e);if(document.querySelector(`link[rel="stylesheet"][href="${e}"]`))return void t();const n=document.createElement("link");n.setAttribute("rel","stylesheet"),n.setAttribute("href",e),n.addEventListener("load",(()=>{this.snowboard.globalEvent("assetLoader.loaded","style",e,n),t()})),n.addEventListener("error",(()=>{this.snowboard.globalEvent("assetLoader.error","style",e,n),s(new Error(`Unable to load stylesheet file: "${e}"`))})),document.head.append(n)}))}loadImage(e){return new Promise(((t,s)=>{e=this.snowboard.url().asset(e);const n=new Image;n.addEventListener("load",(()=>{this.snowboard.globalEvent("assetLoader.loaded","image",e,n),t()})),n.addEventListener("error",(()=>{this.snowboard.globalEvent("assetLoader.error","image",e,n),s(new Error(`Unable to load image file: "${e}"`))})),n.src=e}))}}},293:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{dependencies(){return["request"]}listens(){return{ajaxStart:"ajaxStart",ajaxDone:"ajaxDone"}}ajaxStart(e,t){if(t.element)if("FORM"===t.element.tagName){const e=t.element.querySelectorAll("[data-attach-loading]");e.length>0&&e.forEach((e=>{e.classList.add(this.getLoadingClass(e))}))}else void 0!==t.element.dataset.attachLoading&&t.element.classList.add(this.getLoadingClass(t.element))}ajaxDone(e,t){if(t.element)if("FORM"===t.element.tagName){const e=t.element.querySelectorAll("[data-attach-loading]");e.length>0&&e.forEach((e=>{e.classList.remove(this.getLoadingClass(e))}))}else void 0!==t.element.dataset.attachLoading&&t.element.classList.remove(this.getLoadingClass(t.element))}getLoadingClass(e){return void 0!==e.dataset.attachLoading&&""!==e.dataset.attachLoading?e.dataset.attachLoading:"wn-loading"}}},490:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{construct(e,t,s){if(e instanceof n.A==!1)throw new Error("You must provide a Snowboard plugin to enable data configuration");if(t instanceof HTMLElement==!1)throw new Error("Data configuration can only be extracted from HTML elements");this.instance=e,this.element=t,this.localConfig=s||{},this.instanceConfig={},this.acceptedConfigs={},this.refresh()}get(e){return void 0===e?this.instanceConfig:void 0!==this.instanceConfig[e]?this.instanceConfig[e]:void 0}set(e,t,s){if(void 0===e)throw new Error("You must provide a configuration key to set");this.instanceConfig[e]=t,!0===s&&(this.element.dataset[e]=t,this.localConfig[e]=t)}refresh(){this.acceptedConfigs=this.getAcceptedConfigs(),this.instanceConfig=this.processConfig()}getAcceptedConfigs(){return void 0!==this.instance.acceptAllDataConfigs&&!0===this.instance.acceptAllDataConfigs||void 0!==this.instance.defaults&&"function"==typeof this.instance.defaults&&"object"==typeof this.instance.defaults()&&Object.keys(this.instance.defaults())}getDefaults(){return void 0!==this.instance.defaults&&"function"==typeof this.instance.defaults&&"object"==typeof this.instance.defaults()?this.instance.defaults():{}}processConfig(){const e=this.getDefaults();if(!1===this.acceptedConfigs)return e;for(const t in this.element.dataset)(!0===this.acceptedConfigs||this.acceptedConfigs.includes(t))&&(e[t]=this.coerceValue(this.element.dataset[t]));for(const t in this.localConfig)(!0===this.acceptedConfigs||this.acceptedConfigs.includes(t))&&(e[t]=this.localConfig[t]);return e}coerceValue(e){const t=String(e);if("null"===t)return null;if("undefined"!==t){if(t.startsWith("base64:")){const e=t.replace(/^base64:/,""),s=atob(e);return this.coerceValue(s)}if(["true","yes"].includes(t.toLowerCase()))return!0;if(["false","no"].includes(t.toLowerCase()))return!1;if(/^[-+]?[0-9]+(\.[0-9]+)?$/.test(t))return Number(t);try{return this.snowboard.jsonParser().parse(t)}catch(e){return""===t||t}}}}},336:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{construct(e,t,s){if(this.message=e,this.type=t||"default",this.duration=Number(s||7),this.duration<0)throw new Error("Flash duration must be a positive number, or zero");this.clear(),this.timer=null,this.flashTimer=null,this.create()}dependencies(){return["transition"]}destruct(){null!==this.timer&&window.clearTimeout(this.timer),this.flashTimer&&this.flashTimer.remove(),this.flash&&(this.flash.remove(),this.flash=null,this.flashTimer=null),super.destruct()}create(){this.snowboard.globalEvent("flash.create",this),this.flash=document.createElement("DIV"),this.flash.innerHTML=this.message,this.flash.classList.add("flash-message",this.type),this.flash.removeAttribute("data-control"),this.flash.addEventListener("click",(()=>this.remove())),this.flash.addEventListener("mouseover",(()=>this.stopTimer())),this.flash.addEventListener("mouseout",(()=>this.startTimer())),this.duration>0?(this.flashTimer=document.createElement("DIV"),this.flashTimer.classList.add("flash-timer"),this.flash.appendChild(this.flashTimer)):this.flash.classList.add("no-timer"),document.body.appendChild(this.flash),this.snowboard.transition(this.flash,"show",(()=>{this.startTimer()}))}remove(){this.snowboard.globalEvent("flash.remove",this),this.stopTimer(),this.snowboard.transition(this.flash,"hide",(()=>{this.flash.remove(),this.flash=null,this.destruct()}))}clear(){document.querySelectorAll("body > div.flash-message").forEach((e=>e.remove()))}startTimer(){0!==this.duration&&(this.timerTrans=this.snowboard.transition(this.flashTimer,"timeout",null,`${this.duration}.0s`,!0),this.timer=window.setTimeout((()=>this.remove()),1e3*this.duration))}stopTimer(){this.timerTrans&&this.timerTrans.cancel(),this.timer&&window.clearTimeout(this.timer)}}},758:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{dependencies(){return["request"]}listens(){return{ready:"ready",ajaxStart:"ajaxStart"}}ready(){this.counter=0,this.createStripe()}ajaxStart(e,t){!1!==t.options.stripe&&(this.show(),e.then((()=>{this.hide()})).catch((()=>{this.hide()})))}createStripe(){this.indicator=document.createElement("DIV"),this.stripe=document.createElement("DIV"),this.stripeLoaded=document.createElement("DIV"),this.indicator.classList.add("stripe-loading-indicator","loaded"),this.stripe.classList.add("stripe"),this.stripeLoaded.classList.add("stripe-loaded"),this.indicator.appendChild(this.stripe),this.indicator.appendChild(this.stripeLoaded),document.body.appendChild(this.indicator)}show(){this.counter+=1;const e=this.stripe.cloneNode(!0);this.indicator.appendChild(e),this.stripe.remove(),this.stripe=e,this.counter>1||(this.indicator.classList.remove("loaded"),document.body.classList.add("wn-loading"))}hide(e){this.counter-=1,!0===e&&(this.counter=0),this.counter<=0&&(this.indicator.classList.add("loaded"),document.body.classList.remove("wn-loading"))}}},75:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{listens(){return{ready:"ready"}}ready(){let e=!1;if(document.querySelectorAll('link[rel="stylesheet"]').forEach((t=>{t.href.endsWith("/modules/system/assets/css/snowboard.extras.css")&&(e=!0)})),!e){const e=document.createElement("link");e.setAttribute("rel","stylesheet"),e.setAttribute("href",this.snowboard.url().asset("/modules/system/assets/css/snowboard.extras.css")),document.head.appendChild(e)}}}},843:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{construct(e,t,s,n,i){if(e instanceof HTMLElement==!1)throw new Error("A HTMLElement must be provided for transitioning");if(this.element=e,"string"!=typeof t)throw new Error("Transition name must be specified as a string");if(this.transition=t,s&&"function"!=typeof s)throw new Error("Callback must be a valid function");this.callback=s,this.duration=n?this.parseDuration(n):null,this.trailTo=!0===i,this.doTransition()}eventClasses(){for(var e=arguments.length,t=new Array(e),s=0;s{const[s,n]=e;-1!==t.indexOf(s)&&i.push(n)})),i}doTransition(){null!==this.duration&&(this.element.style.transitionDuration=this.duration),this.resetClasses(),this.eventClasses("in","active").forEach((e=>{this.element.classList.add(e)})),window.requestAnimationFrame((()=>{"0s"!==window.getComputedStyle(this.element)["transition-duration"]?(this.element.addEventListener("transitionend",(()=>this.onTransitionEnd()),{once:!0}),window.requestAnimationFrame((()=>{this.element.classList.remove(this.eventClasses("in")[0]),this.element.classList.add(this.eventClasses("out")[0])}))):(this.resetClasses(),this.callback&&this.callback.apply(this.element),this.destruct())}))}onTransitionEnd(){this.eventClasses("active",this.trailTo?"":"out").forEach((e=>{this.element.classList.remove(e)})),this.callback&&this.callback.apply(this.element),null!==this.duration&&(this.element.style.transitionDuration=null),this.destruct()}cancel(){this.element.removeEventListener("transitionend",(()=>this.onTransitionEnd),{once:!0}),this.resetClasses(),null!==this.duration&&(this.element.style.transitionDuration=null),this.destruct()}resetClasses(){this.eventClasses().forEach((e=>{this.element.classList.remove(e)}))}parseDuration(e){const t=/^([0-9]+(\.[0-9]+)?)(m?s)?$/.exec(e),s=Number(t[1]);return"sec"===("s"===t[3]?"sec":"msec")?1e3*s+"ms":`${Math.floor(s)}ms`}}},54:function(e,t){t.A={get(e,t,s){if("string"==typeof t){const s=t.toLowerCase();if(e.hasPlugin(s))return function(){return Reflect.get(e,"plugins")[s].getInstance(...arguments)}}return Reflect.get(e,t,s)},has(e,t){if("string"==typeof t){const s=t.toLowerCase();if(e.hasPlugin(s))return!0}return Reflect.has(e,t)}}},160:function(e,t,s){s.d(t,{A:function(){return g}});var n=s(660),i=s(373),r={get(e,t,s){if("string"==typeof t){const s=t.toLowerCase();if(["attachAbstracts","loadUtilities","initialise","initialiseSingletons"].includes(t))throw new Error(`You cannot use the "${t}" Snowboard method within a plugin.`);if(e.hasPlugin(s))return function(){return Reflect.get(e,"plugins")[s].getInstance(...arguments)}}return Reflect.get(e,t,s)},has(e,t){if("string"==typeof t){const s=t.toLowerCase();if(["attachAbstracts","loadUtilities","initialise","initialiseSingletons"].includes(t))return!1;if(e.hasPlugin(s))return!0}return Reflect.has(e,t)}};class o{constructor(e,t,s){this.name=e,this.snowboard=new Proxy(t,r),this.instance=s,Object.freeze(this.instance),this.instances=[],this.singleton={initialised:!1},Object.seal(this.singleton),this.mocks={},this.originalFunctions={},Object.freeze(o.prototype),Object.freeze(this)}hasMethod(e){return!this.isFunction()&&"function"==typeof this.instance.prototype[e]}callMethod(){if(this.isFunction())return null;for(var e=arguments.length,t=new Array(e),s=0;s!this.snowboard.getPluginNames().includes(e)));throw new Error(`The "${this.name}" plugin requires the following plugins: ${e.join(", ")}`)}if(this.isSingleton())return 0===this.instances.length&&this.initialiseSingleton(...s),Object.keys(this.mocks).length>0&&(Object.entries(this.originalFunctions).forEach((e=>{const[t,s]=e;this.instances[0][t]=s})),Object.entries(this.mocks).forEach((t=>{const[s,n]=t;this.instances[0][s]=function(){for(var t=arguments.length,s=new Array(t),i=0;i0&&(Object.entries(this.originalFunctions).forEach((e=>{const[t,s]=e;this.instance.prototype[t]=s})),Object.entries(this.mocks).forEach((t=>{const[s,n]=t;this.instance.prototype[s]=function(){for(var t=arguments.length,s=new Array(t),i=0;ithis.instances.splice(this.instances.indexOf(i),1),i.construct(...s),this.instances.push(i),i}getInstances(){return this.isFunction()?[]:this.instances}isFunction(){return"function"==typeof this.instance&&this.instance.prototype instanceof n.A==!1}isSingleton(){return this.instance.prototype instanceof i.A==!0}isInitialised(){return!this.isSingleton()||this.singleton.initialised}initialiseSingleton(){if(!this.isSingleton())return;for(var e=arguments.length,t=new Array(e),s=0;sthis.instances.splice(this.instances.indexOf(n),1),n.construct(...t),this.instances.push(n),this.singleton.initialised=!0}getDependencies(){return this.isFunction()||"function"!=typeof this.instance.prototype.dependencies?[]:this.instance.prototype.dependencies().map((e=>e.toLowerCase()))}dependenciesFulfilled(){const e=this.getDependencies();let t=!0;return e.forEach((e=>{this.snowboard.hasPlugin(e)||(t=!1)})),t}mock(e,t){var s=this;if(!this.isFunction()){if(!this.instance.prototype[e])throw new Error(`Function "${e}" does not exist and cannot be mocked`);this.mocks[e]=t,this.originalFunctions[e]=this.instance.prototype[e],this.isSingleton()&&0===this.instances.length&&(this.initialiseSingleton(),this.instances[0][e]=function(){for(var e=arguments.length,n=new Array(e),i=0;i{const[t,s]=e;void 0!==this.defaults[t]&&(this.defaults[t]=s)}))}getDefaults(){const e={};return Object.entries(this.defaults).forEach((t=>{const[s,n]=t;null!==this.defaults[s]&&(e[s]=n)})),e}get(e){if(void 0===e){const e=a.A.get();return Object.entries(e).forEach((t=>{const[s,n]=t;this.snowboard.globalEvent("cookie.get",s,n,(t=>{e[s]=t}))})),e}let t=a.A.get(e);return this.snowboard.globalEvent("cookie.get",e,t,(e=>{t=e})),t}set(e,t,s){let n=t;return this.snowboard.globalEvent("cookie.set",e,t,(e=>{n=e})),a.A.set(e,n,h(h({},this.getDefaults()),s))}remove(e,t){a.A.remove(e,h(h({},this.getDefaults()),t))}}class u extends i.A{construct(){window.wnJSON=e=>this.parse(e),window.ocJSON=window.wnJSON}parse(e){const t=this.parseString(e);return JSON.parse(t)}parseString(e){let t=e.trim();if(!t.length)throw new Error("Broken JSON object.");let s="",n=null,i=null,r="";for(;t&&","===t[0];)t=t.substr(1);if('"'===t[0]||"'"===t[0]){if(t[t.length-1]!==t[0])throw new Error("Invalid string JSON object.");r='"';for(let e=1;e="0"&&e[t]<="9"){s="";for(let n=t;n="0"&&e[n]<="9"))return{originLength:s.length,body:s};s+=e[n]}throw new Error(`Broken JSON number body near ${s}`)}if("{"===e[t]||"["===e[t]){const n=[e[t]];s=e[t];for(let i=t+1;i=0?t-5:0,50)}`)}parseKey(e,t,s){let n="";for(let i=t;i="a"&&e[0]<="z"||e[0]>="A"&&e[0]<="Z"||"_"===e[0]||(e[0]>="0"&&e[0]<="9"||("$"===e[0]||e.charCodeAt(0)>255)))}isBlankChar(e){return" "===e||"\n"===e||"\t"===e}}class f extends i.A{construct(){window.wnSanitize=e=>this.sanitize(e),window.ocSanitize=window.wnSanitize}sanitize(e,t){const s=(new DOMParser).parseFromString(e,"text/html"),n=void 0===t||"boolean"!=typeof t||t;return this.sanitizeNode(s.getRootNode()),n?s.body.innerHTML:s.innerHTML}sanitizeNode(e){if("SCRIPT"===e.tagName)return void e.remove();this.trimAttributes(e);Array.from(e.children).forEach((e=>{this.sanitizeNode(e)}))}trimAttributes(e){if(e.attributes)for(let t=0;t{this.autoInitSingletons&&this.initialiseSingletons(),this.globalEvent("ready"),this.readiness.dom=!0}))}initialiseSingletons(){Object.values(this.plugins).forEach((e=>{e.isSingleton()&&e.dependenciesFulfilled()&&e.initialiseSingleton()}))}addPlugin(e,t){const s=e.toLowerCase();if(this.hasPlugin(s))throw new Error(`A plugin called "${e}" is already registered.`);if("function"!=typeof t&&t instanceof n.A==!1)throw new Error("The provided plugin must extend the PluginBase class, or must be a callback function.");if(void 0!==this[e]||void 0!==this[s])throw new Error("The given name is already in use for a property or method of the Snowboard class.");this.plugins[s]=new o(s,this,t),this.debug(`Plugin "${e}" registered`),Object.values(this.getPlugins()).forEach((e=>{if(e.isSingleton()&&!e.isInitialised()&&e.dependenciesFulfilled()&&e.hasMethod("listens")&&Object.keys(e.callMethod("listens")).includes("ready")&&this.readiness.dom){const t=e.callMethod("listens").ready;e.callMethod(t)}}))}removePlugin(e){const t=e.toLowerCase();this.hasPlugin(t)?(this.plugins[t].getInstances().forEach((e=>{e.destruct()})),delete this.plugins[t],delete this[t],delete this[e],this.debug(`Plugin "${e}" removed`)):this.debug(`Plugin "${e}" already removed`)}hasPlugin(e){const t=e.toLowerCase();return void 0!==this.plugins[t]}getPlugins(){return this.plugins}getPluginNames(){return Object.keys(this.plugins)}getPlugin(e){const t=e.toLowerCase();if(!this.hasPlugin(t))throw new Error(`No plugin called "${t}" has been registered.`);return this.plugins[t]}listensToEvent(e){const t=[];return Object.entries(this.plugins).forEach((s=>{const[n,i]=s;if(i.isFunction())return;if(!i.dependenciesFulfilled())return;if(!i.hasMethod("listens"))return;const r=i.callMethod("listens");"string"!=typeof r[e]&&"function"!=typeof r[e]||t.push(n)})),t}ready(e){this.readiness.dom&&e(),this.on("ready",e)}on(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].includes(t)||this.listeners[e].push(t)}off(e,t){if(!this.listeners[e])return;const s=this.listeners[e].indexOf(t);-1!==s&&this.listeners[e].splice(s,1)}globalEvent(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n{const n=this.getPlugin(t);if(n.isFunction())return;n.isSingleton()&&0===n.getInstances().length&&n.initialiseSingleton();const i=n.callMethod("listens")[e];n.getInstances().forEach((n=>{if(!r)if("function"==typeof i)try{!1===i.apply(n,s)&&(r=!0)}catch(s){this.error(`Error thrown in "${e}" event by "${t}" plugin.`,s)}else if("string"==typeof i){if(!n[i])throw new Error(`Missing "${i}" method in "${t}" plugin`);try{!1===n[i](...s)&&(r=!0,this.debug(`Global event "${e}" cancelled by "${t}" plugin`))}catch(s){this.error(`Error thrown in "${e}" event by "${t}" plugin.`,s)}}else this.error(`Listen method for "${e}" event in "${t}" plugin is not a function or string.`)}))})),!r&&this.listeners[e]&&this.listeners[e].length>0&&(this.debug(`Found ${this.listeners[e].length} ad-hoc listener(s) for global event "${e}"`),this.listeners[e].forEach((t=>{if(!r)try{!1===t(...s)&&(r=!0,this.debug(`Global event "${e} cancelled by an ad-hoc listener.`))}catch(t){this.error(`Error thrown in "${e}" event by an ad-hoc listener.`,t)}}))),!r}globalPromiseEvent(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n{const n=this.getPlugin(t);if(n.isFunction())return;n.isSingleton()&&0===n.getInstances().length&&n.initialiseSingleton();const i=n.callMethod("listens")[e];n.getInstances().forEach((n=>{if("function"==typeof i)try{const e=i.apply(n,s);if(e instanceof Promise==!1)return;r.push(e)}catch(s){this.error(`Error thrown in "${e}" event by "${t}" plugin.`,s)}else if("string"==typeof i){if(!n[i])throw new Error(`Missing "${i}" method in "${t}" plugin`);try{const e=n[i](...s);if(e instanceof Promise==!1)return;r.push(e)}catch(s){this.error(`Error thrown in "${e}" promise event by "${t}" plugin.`,s)}}else this.error(`Listen method for "${e}" event in "${t}" plugin is not a function or string.`)}))})),this.listeners[e]&&this.listeners[e].length>0&&(this.debug(`Found ${this.listeners[e].length} ad-hoc listener(s) for global promise event "${e}"`),this.listeners[e].forEach((t=>{try{const e=t(...s);if(e instanceof Promise==!1)return;r.push(e)}catch(t){this.error(`Error thrown in "${e}" promise event by an ad-hoc listener.`,t)}}))),0===r.length?Promise.resolve():Promise.all(r)}logMessage(e,t,s){console.groupCollapsed("%c[Snowboard]",`color: ${e}; font-weight: ${t?"bold":"normal"};`,s);for(var n=arguments.length,i=new Array(n>3?n-3:0),r=3;r{e+=1,console.log(`%c${e}:`,"color: rgb(88, 88, 88); font-weight: normal;",t)})),console.groupEnd(),console.groupCollapsed("%cTrace","color: rgb(45, 167, 199); font-weight: bold;"),console.trace(),console.groupEnd()}else console.trace();console.groupEnd()}log(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n1?t-1:0),n=1;n1?t-1:0),n=1;n0&&(this.resetEvents(),this.createTriggerEvents(),this.runEvents(),this.snowboard.globalEvent("triggers.ready",this.element,this.triggers))}destruct(){this.resetEvents(),super.destruct()}parseTriggers(){const{dataset:e}=this.element;this.triggers.clear(),Object.keys(e).forEach((t=>{if(/-[A-Z]/.test(t))throw new Error(`Unable to convert camelCase to dash-style for data attribute: ${t}`);const s=t.replace(/([A-Z])/g,(e=>`-${e.toLowerCase()}`));if("trigger"!==s&&!s.startsWith("trigger-"))return;const n=/([a-z0-9\-.:_]+?)(?:(?:-)(closest-parent|condition|when|action|parent|priority|do))?(?:(?<=(?:action|do)(\.oneway)?)(\.oneway))?$/i.exec(s.replace("trigger-","").toLowerCase());let i=null,r=null;if(-1!==["trigger","condition","action","parent","when","closest"].indexOf(n[1])&&("closest"!==n[1]||"closest"===n[1]&&"parent"===n[2]))i="__original",r="closest"===n[1]?"parent":n[1];else if(void 0===n[2]||-1!==["closest-parent","condition","when","action","parent","priority","do"].indexOf(n[2]))switch([,i]=n,n[2]){case"closest-parent":case"parent":r="parent";break;case"condition":case"when":r="condition";break;case"action":case"do":r="action";break;case"priority":r="priority";break;default:r="trigger"}this.triggers.has(i)||this.triggers.set(i,new Map),this.triggers.get(i).set(r,e[t]),delete e[t]})),this.triggers.forEach(((e,t)=>{const s=this.getSelectableElements(e);e.has("trigger")&&e.has("condition")&&e.has("action")&&0!==s.length&&this.hasValidConditions(e)&&this.hasValidActions(e)?(e.set("elements",s),e.has("priority")||e.set("priority",100)):this.triggers.delete(t)}))}parseCommand(e){let t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(e.startsWith("value")&&e.includes("[")){const t=e.match(/[^[\]]+(?=])/g),s=[];return t.forEach((e=>{if(!e.includes(","))return void s.push(e.replace(/^['"]|['"]$/g,"").trim());const t=e.replace(/('.*?(?e.replace(/,/g,"|||"))).split(",").map((e=>e.replace(/\|\|\|/g,",").replace(/^['"]|['"]$/g,"").trim()));s.push(...t)})),[{name:"value",parameters:s,oneWay:!1}]}if(e.includes("|")&&t){const t=e.replace(/('.*?(?e.replace(/\|/g,"|||"))).split("|").map((e=>e.replace(/\|\|\|/g,"|"))),s=[];return t.forEach((e=>{s.push(...this.parseCommand(e,!1))})),s}if(!e.includes(":"))return e.includes(".oneway")&&(e.startsWith("do")||e.startsWith("action"))?[{name:e.replace(".oneway",""),parameters:[],oneWay:!0}]:[{name:e,parameters:[],oneWay:!1}];const[,s,n]=e.match(/^([a-zA-Z]+):(.*)$/);let i=s,r=!1;if(s.includes(".oneway")&&(s.startsWith("do")||s.startsWith("action"))&&(i=e.replace(".oneway",""),r=!0),!n.includes(","))return[{name:i,parameters:[n.replace(/^['"]|['"]$/g,"").replace(/\\(['"])/,"$1").trim()],oneWay:r}];return[{name:i,parameters:n.replace(/('.*?(?e.replace(/,/g,"|||"))).split(",").map((e=>e.replace(/\|\|\|/g,",").replace(/^['"]|['"]$/g,"").replace(/\\(['"])/,"$1").trim())),oneWay:r}]}getSelectableElements(e){return e.has("parent")?this.element.closest(e.get("parent"))?Array.from(this.element.closest(e.get("parent")).querySelectorAll(e.get("trigger"))):[]:Array.from(document.querySelectorAll(e.get("trigger")))}hasValidConditions(e){return this.parseCommand(e.get("condition")).every((e=>["checked","unchecked","empty","value","oneof","allof","focus","within","notWithin"].includes(e.name.toLowerCase())))}hasValidActions(e){return this.parseCommand(e.get("action")).every((e=>["show","hide","enable","disable","empty","value","valueOf","check","uncheck","class","classOf","attr","attrOf","style","styleOf"].includes(e.name.toLowerCase())))}createTriggerEvents(){this.triggers.forEach((e=>{e.set("conditionCallbacks",[]),e.set("elementEvents",new Map),this.parseCommand(e.get("condition")).forEach((t=>{switch(t.name.toLowerCase()){case"value":case"oneof":e.get("conditionCallbacks").push(this.createValueCondition(e,!1,...t.parameters));break;case"allof":e.get("conditionCallbacks").push(this.createValueCondition(e,!0,...t.parameters));break;case"empty":e.get("conditionCallbacks").push(this.createEmptyCondition(e));break;case"checked":case"unchecked":e.get("conditionCallbacks").push(this.createCheckedCondition(e,"checked"===t.name,...t.parameters));break;case"focus":e.get("conditionCallbacks").push(this.createFocusedCondition(e));break;case"within":case"notwithin":e.get("conditionCallbacks").push(this.createWithinCondition(e,"within"===t.name,...t.parameters))}}))})),this.registerEventListeners()}addEvent(e,t,s){t.get("elementEvents").has(e)||t.get("elementEvents").set(e,new Set),t.get("elementEvents").get(e).add(s)||t.get("elementEvents").get(e).add(s)}registerEventListeners(){const e=new Set;this.triggers.forEach((t=>{t.get("elementEvents").forEach(((s,n)=>{this.events.has(n)||this.events.set(n,new Set),s.forEach((s=>{e.has({element:n,eventName:s})||e.add({element:n,eventName:s});const i={element:n,eventName:s,priority:Number(t.get("priority")),event:()=>{let e=null;this.executeActions(t,t.get("conditionCallbacks").every((t=>{const s=t(e);return!1!==s&&(e=s,!0)})))}};this.events.get(n).add(i)}))}))})),e.forEach((e=>{let{element:t,eventName:s}=e;this.connectors.has(t)||this.connectors.set(t,new Map),this.connectors.get(t).has(s)||(this.connectors.get(t).set(s,(()=>{const e=[];this.events.get(t).forEach((t=>{t.eventName===s&&e.push(t)})),e.sort(((e,t)=>e.priority-t.priority)).forEach((e=>{e.event()}))})),t.addEventListener(s,this.connectors.get(t).get(s)))}))}createValueCondition(e,t){for(var s=arguments.length,n=new Array(s>2?s-2:0),i=2;i{e.matches("input[type=button], input[type=file], input[type=image], input[type=reset], input[type=submit]")||e.matches("input, select, textarea")&&r.add(e)})),r.forEach((t=>{if(t.matches("input[type=checkbox], input[type=radio]"))return this.addEvent(t,e,"click"),void this.addEvent(t,e,"change");t.matches("input[type=hidden]")?this.addEvent(t,e,"change"):this.addEvent(t,e,"input")})),function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;const s=new Map;(e??r).forEach((e=>{e.matches("input[type=checkbox], input[type=radio]")?e.checked&&s.set(e,e.value):s.set(e,e.value)}));return!!(t?n.every((e=>s.values().find((t=>t===e)))):n.some((e=>s.values().find((t=>t===e)))))&&Array.from(s.entries().filter((e=>{let[,t]=e;return n.includes(t)})).map((e=>{let[,t]=e;return t})))}}createEmptyCondition(e){const t=new Set;return e.get("elements").forEach((e=>{e.matches("input[type=button], input[type=image], input[type=reset], input[type=submit]")||e.matches("input, select, textarea")&&t.add(e)})),t.forEach((t=>{if(t.matches("input[type=checkbox], input[type=radio]"))return this.addEvent(t,e,"click"),void this.addEvent(t,e,"change");this.addEvent(t,e,"input")})),function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;const s=new Set,n=e??t;n.forEach((e=>{e.matches("input[type=checkbox], input[type=radio]")?e.checked&&s.add(e):""!==e.value.trim()&&s.add(e)}));return!(0!==s.size)&&Array.from(n.keys().filter((e=>!s.has(e))))}}createCheckedCondition(e,t){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:void 0;const i=new Set;return e.get("elements").forEach((e=>{e.matches("input[type=radio], input[type=checkbox]")&&i.add(e)})),i.forEach((t=>{this.addEvent(t,e,"click")})),function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;const r=new Set,o=e??i;if(o.forEach((e=>{t===e.checked&&r.add(e)})),"all"===s)return r.size===o.size&&Array.from(r);const a=void 0!==s&&Math.floor(s)>0?Math.floor(s):1,l=void 0!==s&&Math.floor(n)>0?Math.floor(n):i.size;return r.size>=a&&r.size<=l&&Array.from(r)}}createFocusedCondition(e){const t=new Set;return e.get("elements").forEach((e=>{t.add(e)})),t.forEach((t=>{this.addEvent(t,e,"focus"),this.addEvent(t,e,"blur")})),function(){const e=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:null)??t,s=Array.from(e).find((e=>document.activeElement===e));return!!s&&[s]}}createWithinCondition(e,t,s){const n=new Set;return e.get("elements").forEach((e=>{n.add(e)})),n.forEach((t=>{this.addEvent(t,e,"click"),this.addEvent(t,e,"change"),this.addEvent(t,e,"focus"),this.addEvent(t,e,"blur")})),function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;const i=new Set,r=e??n;return r.forEach((e=>{let n=!1;document.querySelectorAll(s).forEach((t=>{!0!==n&&t.contains(e)&&(n=!0)})),n===t&&i.add(e)})),i.size===r.length&&Array.from(i)}}runEvents(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0;this.connectors.forEach(((t,s)=>{e&&s!==e||t.forEach((e=>{e()}))}))}resetEvents(){this.connectors.forEach(((e,t)=>{e.forEach(((e,s)=>{t.removeEventListener(s,e)}))})),this.connectors.clear(),this.events.clear()}executeActions(e,t){this.parseCommand(e.get("action")).forEach((s=>{if(!1!==this.snowboard.globalEvent("trigger.action",this.element,e,s,t)){if(!s.oneWay||t)switch(s.name){case"show":case"hide":this.actionShow(e,t,s.parameters[0]?Array.from(this.element.querySelectorAll(s.parameters[0])):[this.element],"show"===s.name?t:!t);break;case"enable":case"disable":this.actionEnable(e,t,s.parameters[0]?Array.from(this.element.querySelectorAll(s.parameters[0])):[this.element],"enable"===s.name?t:!t);break;case"empty":t&&this.actionValue(e,t,s.parameters[0]?Array.from(this.element.querySelectorAll(s.parameters[0])):[this.element],"");break;case"value":case"valueOf":this.actionValue(e,t,"valueOf"===s.name?Array.from(this.element.querySelectorAll(s.parameters[0])):[this.element],...s.parameters.length>0&&"valueOf"===s.name?s.parameters.slice(1):s.parameters);break;case"class":case"classOf":this.actionClass(e,t,"classOf"===s.name?Array.from(this.element.querySelectorAll(s.parameters[0])):[this.element],..."classOf"===s.name?s.parameters.slice(1):s.parameters)}}else this.afterAction(e,this.element,{action:s.name,override:!0,conditionMet:t})}))}actionShow(e,t,s,n){s.forEach((s=>{!n||s.style.display&&"none"!==s.style.display?n||s.style.display&&"none"===s.style.display||(s.style.display&&(s.dataset.originalDisplay=s.style.display),s.style.display="none",this.afterAction(e,s,{action:"show",conditionMet:t,show:n})):(void 0!==s.dataset.originalDisplay?(s.style.display=s.dataset.originalDisplay,delete s.dataset.originalDisplay):s.style.display&&(s.style.display=null),this.afterAction(e,s,{action:"show",conditionMet:t,show:n}))}))}actionEnable(e,t,s,n){s.forEach((s=>{s.classList[n?"remove":"add"]("control-disabled"),void 0!==s.disabled&&(s.disabled=!n),this.afterAction(e,s,{action:"enable",conditionMet:t,enable:n})}))}actionValue(e,t,s,n){let i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:void 0;if(!t&&void 0===i)return;const r=t?n:i;s.forEach((s=>{s.matches("input[type=checkbox], input[type=radio]")?s.checked=s.value===r:s.matches("input, select, textarea")?s.value=r:(s.textContent=r,this.afterAction(e,s,{action:"value",conditionMet:t,value:n,unmetValue:i}))}))}actionClass(e,t,s,n){let i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:void 0;s.forEach((s=>{t?(s.classList.add(n),i&&s.classList.remove(i)):(s.classList.remove(n),i&&s.classList.add(i)),this.afterAction(e,s,{action:"class",conditionMet:t,cssClass:n,unmetCssClass:i})}))}afterAction(e,t,s){this.snowboard.debug("Trigger fired",t,e,s),this.snowboard.globalEvent("trigger.fired",t,e,s)}}if(void 0===window.Snowboard)throw new Error("Snowboard must be loaded in order to use the extra plugins.");(n=window.Snowboard).addPlugin("assetLoader",h.A),n.addPlugin("dataConfig",c.A),n.addPlugin("extrasStyles",l.A),n.addPlugin("transition",r.A),n.addPlugin("flash",i.A),n.addPlugin("attachLoading",o.A),n.addPlugin("stripeLoader",a.A),n.addPlugin("trigger",u)},799:function(e,t,s){var n=s(160),i=s(54);(e=>{const t=new Proxy(new n.A(!0,!0),i.A);e.snowboard=t,e.Snowboard=t,e.SnowBoard=t})(window)},59:function(e,t,s){var n=s(660);function i(e,t){var s=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),s.push.apply(s,n)}return s}function r(e){for(var t=1;t{e&&this.doAjax().then((e=>{if(e.cancelled)return this.cancelled=!0,void this.complete();this.responseData=e,this.processUpdate(e).then((()=>{!1===e.X_WINTER_SUCCESS?this.processError(e):this.processResponse(e)}))}),(e=>{this.responseError=e,this.processError(e)}))})):this.doAjax().then((e=>{if(e.cancelled)return this.cancelled=!0,void this.complete();this.responseData=e,this.processUpdate(e).then((()=>{!1===e.X_WINTER_SUCCESS?this.processError(e):this.processResponse(e)}))}),(e=>{this.responseError=e,this.processError(e)})):this.cancelled=!0}else this.cancelled=!0}dependencies(){return["cookie","jsonParser"]}checkRequest(){if(this.element&&this.element instanceof Element==!1)throw new Error("The element provided must be an Element instance");if(void 0===this.handler)throw new Error("The AJAX handler name is not specified.");if(!this.isHandlerName(this.handler))throw new Error('Invalid AJAX handler name. The correct handler name format is: "onEvent".')}getFetch(){return this.fetchOptions=void 0!==this.options.fetchOptions&&"object"==typeof this.options.fetchOptions?this.options.fetchOptions:{method:"POST",headers:this.headers,body:this.data,redirect:"follow",mode:"same-origin"},this.snowboard.globalEvent("ajaxFetchOptions",this.fetchOptions,this),fetch(this.url,this.fetchOptions)}doClientValidation(){return!0!==this.options.browserValidate||!this.form||!1!==this.form.checkValidity()||(this.form.reportValidity(),!1)}doAjax(){if(!1===this.snowboard.globalEvent("ajaxBeforeSend",this))return Promise.resolve({cancelled:!0});const e=new Promise(((e,t)=>{this.getFetch().then((s=>{s.ok||406===s.status?s.headers.has("Content-Type")&&s.headers.get("Content-Type").includes("/json")?s.json().then((t=>{e(r(r({},t),{},{X_WINTER_SUCCESS:406!==s.status,X_WINTER_RESPONSE_CODE:s.status}))}),(e=>{t(this.renderError(`Unable to parse JSON response: ${e}`))})):s.text().then((t=>{e(t)}),(e=>{t(this.renderError(`Unable to process response: ${e}`))})):s.headers.has("Content-Type")&&s.headers.get("Content-Type").includes("/json")?s.json().then((e=>{e.message&&e.exception?t(this.renderError(e.message,e.exception,e.file,e.line,e.trace)):t(e)}),(e=>{t(this.renderError(`Unable to parse JSON response: ${e}`))})):s.text().then((e=>{t(this.renderError(e))}),(e=>{t(this.renderError(`Unable to process response: ${e}`))}))}),(e=>{t(this.renderError(`Unable to retrieve a response from the server: ${e}`))}))}));if(this.snowboard.globalEvent("ajaxStart",e,this),this.element){const t=new Event("ajaxPromise");t.promise=e,this.element.dispatchEvent(t)}return e}processUpdate(e){return new Promise(((t,s)=>{if("function"==typeof this.options.beforeUpdate&&!1===this.options.beforeUpdate.apply(this,[e]))return void t();const n={};if(Object.entries(e).forEach((e=>{const[t,s]=e;"X_WINTER"!==t.substr(0,8)&&(n[t]=s)})),0===Object.keys(n).length)return void(e.X_WINTER_ASSETS?this.processAssets(e.X_WINTER_ASSETS).then((()=>{t()}),(()=>{s()})):t());this.snowboard.globalPromiseEvent("ajaxBeforeUpdate",e,this).then((async()=>{e.X_WINTER_ASSETS&&await this.processAssets(e.X_WINTER_ASSETS),this.doUpdate(n).then((()=>{window.requestAnimationFrame((()=>t()))}),(()=>{s()}))}),(()=>{t()}))}))}doUpdate(e){return new Promise((t=>{const s=[];Object.entries(e).forEach((e=>{const[t,n]=e;let i=this.options.update&&this.options.update[t]?this.options.update[t]:t,r="replace";"@"===i.substr(0,1)?(r="append",i=i.substr(1)):"^"===i.substr(0,1)?(r="prepend",i=i.substr(1)):"#"!==i.substr(0,1)&&"."!==i.substr(0,1)&&(r="noop");const o=document.querySelectorAll(i);o.length>0&&o.forEach((e=>{switch(r){case"append":e.innerHTML+=n;break;case"prepend":e.innerHTML=n+e.innerHTML;break;case"noop":break;default:e.innerHTML=n}s.push(e),this.snowboard.globalEvent("ajaxUpdate",e,n,this);const t=new Event("ajaxUpdate");t.content=n,e.dispatchEvent(t)}))})),this.snowboard.globalEvent("ajaxUpdateComplete",s,this),t()}))}processResponse(e){if((!this.options.success||"function"!=typeof this.options.success||!1!==this.options.success(this.responseData,this))&&!1!==this.snowboard.globalEvent("ajaxSuccess",this.responseData,this)){if(this.element){const e=new Event("ajaxDone",{cancelable:!0});if(e.responseData=this.responseData,e.request=this,this.element.dispatchEvent(e),e.defaultPrevented)return}this.flash&&e.X_WINTER_FLASH_MESSAGES&&this.processFlashMessages(e.X_WINTER_FLASH_MESSAGES),this.redirect||e.X_WINTER_REDIRECT?this.processRedirect(this.redirect||e.X_WINTER_REDIRECT):this.complete()}}processError(e){if((!this.options.error||"function"!=typeof this.options.error||!1!==this.options.error(this.responseError,this))&&!1!==this.snowboard.globalEvent("ajaxError",this.responseError,this)){if(this.element){const e=new Event("ajaxFail",{cancelable:!0});if(e.responseError=this.responseError,e.request=this,this.element.dispatchEvent(e),e.defaultPrevented)return}if(e instanceof Error)this.processErrorMessage(e.message);else{let t=!1;e.X_WINTER_ERROR_FIELDS&&(t=this.processValidationErrors(e.X_WINTER_ERROR_FIELDS)),e.X_WINTER_ERROR_MESSAGE&&!t&&this.processErrorMessage(e.X_WINTER_ERROR_MESSAGE)}this.complete()}}processRedirect(e){"function"==typeof this.options.handleRedirectResponse&&!1===this.options.handleRedirectResponse.apply(this,[e])||!1!==this.snowboard.globalEvent("ajaxRedirect",e,this)&&(window.addEventListener("popstate",(()=>{if(this.element){const e=document.createEvent("CustomEvent");e.eventName="ajaxRedirected",this.element.dispatchEvent(e)}}),{once:!0}),window.location.assign(e))}processErrorMessage(e){"function"==typeof this.options.handleErrorMessage&&!1===this.options.handleErrorMessage.apply(this,[e])||!1!==this.snowboard.globalEvent("ajaxErrorMessage",e,this)&&window.alert(e)}processFlashMessages(e){"function"==typeof this.options.handleFlashMessages&&!1===this.options.handleFlashMessages.apply(this,[e])||this.snowboard.globalEvent("ajaxFlashMessages",e,this)}processValidationErrors(e){return"function"==typeof this.options.handleValidationErrors&&!1===this.options.handleValidationErrors.apply(this,[this.form,e])||!1===this.snowboard.globalEvent("ajaxValidationErrors",this.form,e,this)}processAssets(e){return this.snowboard.globalPromiseEvent("ajaxLoadAssets",e)}async doConfirm(){if("function"==typeof this.options.handleConfirmMessage)return!1!==this.options.handleConfirmMessage.apply(this,[this.confirm]);if(0===this.snowboard.listensToEvent("ajaxConfirmMessage").length)return window.confirm(this.confirm);const e=this.snowboard.globalPromiseEvent("ajaxConfirmMessage",this.confirm,this);try{if(await e)return!0}catch(e){return!1}return!1}complete(){if(this.options.complete&&"function"==typeof this.options.complete&&this.options.complete(this.responseData,this),this.snowboard.globalEvent("ajaxDone",this.responseData,this),this.element){const e=new Event("ajaxAlways");e.request=this,e.responseData=this.responseData,e.responseError=this.responseError,this.element.dispatchEvent(e)}this.destruct()}get form(){return this.options.form?"string"==typeof this.options.form?document.querySelector(this.options.form):this.options.form:this.element?"FORM"===this.element.tagName?this.element:this.element.closest("form"):null}get context(){return{handler:this.handler,options:this.options}}get headers(){const e={"X-Requested-With":"XMLHttpRequest","X-WINTER-REQUEST-HANDLER":this.handler,"X-WINTER-REQUEST-PARTIALS":this.extractPartials(this.options.update||[])};return this.flash&&(e["X-WINTER-REQUEST-FLASH"]=1),this.xsrfToken&&(e["X-XSRF-TOKEN"]=this.xsrfToken),e}get loading(){return this.options.loading||!1}get url(){return this.options.url||window.location.href}get redirect(){return this.options.redirect&&this.options.redirect.length?this.options.redirect:null}get flash(){return this.options.flash||!1}get files(){return!0===this.options.files&&(void 0!==FormData||(this.snowboard.debug("This browser does not support file uploads"),!1))}get xsrfToken(){return this.snowboard.cookie().get("XSRF-TOKEN")}get data(){const e="object"==typeof this.options.data?this.options.data:{},t=new FormData(this.form||void 0);return Object.keys(e).length>0&&this.createFormData(t,e),t}createFormData(e,t){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";"object"==typeof t?Array.isArray(t)&&""!==s?t.forEach((t=>{this.createFormData(e,t,`${s}[]`)})):Object.entries(t).forEach((t=>{const[n,i]=t;this.createFormData(e,i,""!==s?`${s}[${n}]`:n)})):e.append(s,t)}get confirm(){return this.options.confirm||!1}extractPartials(e){return Object.keys(e).join("&")}renderError(e,t,s,n,i){const r=new Error(e);return r.exception=t||null,r.file=s||null,r.line=n||null,r.trace=i||[],r}isHandlerName(e){return/^(?:\w+:{2})?on[A-Z0-9]/.test(e)}}if(void 0===window.Snowboard)throw new Error("Snowboard must be loaded in order to use the Javascript AJAX request feature.");window.Snowboard.addPlugin("request",a)}},function(e){var t=function(t){return e(e.s=t)};e.O(0,[969],(function(){return t(799),t(59),t(222)}));e.O()}]); \ No newline at end of file diff --git a/modules/system/assets/js/build/system.js b/modules/system/assets/js/build/system.js index aedf0cd959..8b753fd089 100644 --- a/modules/system/assets/js/build/system.js +++ b/modules/system/assets/js/build/system.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_wintercms_wn_system_module=self.webpackChunk_wintercms_wn_system_module||[]).push([[336,861,813],{660:function(e,t,s){s.d(t,{A:function(){return n}});class n{constructor(e){this.snowboard=e}construct(){}dependencies(){return[]}listens(){return{}}destruct(){this.detach(),delete this.snowboard}destructor(){this.destruct()}}},373:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{}},477:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{listens(){return{ajaxLoadAssets:"load"}}dependencies(){return["url"]}async load(e){if(e.js&&e.js.length>0)for(const t of e.js)try{await this.loadScript(t)}catch(e){return Promise.reject(e)}if(e.css&&e.css.length>0)for(const t of e.css)try{await this.loadStyle(t)}catch(e){return Promise.reject(e)}if(e.img&&e.img.length>0)for(const t of e.img)try{await this.loadImage(t)}catch(e){return Promise.reject(e)}return Promise.resolve()}loadScript(e){return new Promise(((t,s)=>{e=this.snowboard.url().asset(e);if(document.querySelector(`script[src="${e}"]`))return void t();const n=document.createElement("script");n.setAttribute("type","text/javascript"),n.setAttribute("src",e),n.addEventListener("load",(()=>{this.snowboard.globalEvent("assetLoader.loaded","script",e,n),t()})),n.addEventListener("error",(()=>{this.snowboard.globalEvent("assetLoader.error","script",e,n),s(new Error(`Unable to load script file: "${e}"`))})),document.body.append(n)}))}loadStyle(e){return new Promise(((t,s)=>{e=this.snowboard.url().asset(e);if(document.querySelector(`link[rel="stylesheet"][href="${e}"]`))return void t();const n=document.createElement("link");n.setAttribute("rel","stylesheet"),n.setAttribute("href",e),n.addEventListener("load",(()=>{this.snowboard.globalEvent("assetLoader.loaded","style",e,n),t()})),n.addEventListener("error",(()=>{this.snowboard.globalEvent("assetLoader.error","style",e,n),s(new Error(`Unable to load stylesheet file: "${e}"`))})),document.head.append(n)}))}loadImage(e){return new Promise(((t,s)=>{e=this.snowboard.url().asset(e);const n=new Image;n.addEventListener("load",(()=>{this.snowboard.globalEvent("assetLoader.loaded","image",e,n),t()})),n.addEventListener("error",(()=>{this.snowboard.globalEvent("assetLoader.error","image",e,n),s(new Error(`Unable to load image file: "${e}"`))})),n.src=e}))}}},293:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{dependencies(){return["request"]}listens(){return{ajaxStart:"ajaxStart",ajaxDone:"ajaxDone"}}ajaxStart(e,t){if(t.element)if("FORM"===t.element.tagName){const e=t.element.querySelectorAll("[data-attach-loading]");e.length>0&&e.forEach((e=>{e.classList.add(this.getLoadingClass(e))}))}else void 0!==t.element.dataset.attachLoading&&t.element.classList.add(this.getLoadingClass(t.element))}ajaxDone(e,t){if(t.element)if("FORM"===t.element.tagName){const e=t.element.querySelectorAll("[data-attach-loading]");e.length>0&&e.forEach((e=>{e.classList.remove(this.getLoadingClass(e))}))}else void 0!==t.element.dataset.attachLoading&&t.element.classList.remove(this.getLoadingClass(t.element))}getLoadingClass(e){return void 0!==e.dataset.attachLoading&&""!==e.dataset.attachLoading?e.dataset.attachLoading:"wn-loading"}}},490:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{construct(e,t,s){if(e instanceof n.A==!1)throw new Error("You must provide a Snowboard plugin to enable data configuration");if(t instanceof HTMLElement==!1)throw new Error("Data configuration can only be extracted from HTML elements");this.instance=e,this.element=t,this.localConfig=s||{},this.instanceConfig={},this.acceptedConfigs={},this.refresh()}get(e){return void 0===e?this.instanceConfig:void 0!==this.instanceConfig[e]?this.instanceConfig[e]:void 0}set(e,t,s){if(void 0===e)throw new Error("You must provide a configuration key to set");this.instanceConfig[e]=t,!0===s&&(this.element.dataset[e]=t,this.localConfig[e]=t)}refresh(){this.acceptedConfigs=this.getAcceptedConfigs(),this.instanceConfig=this.processConfig()}getAcceptedConfigs(){return void 0!==this.instance.acceptAllDataConfigs&&!0===this.instance.acceptAllDataConfigs||void 0!==this.instance.defaults&&"function"==typeof this.instance.defaults&&"object"==typeof this.instance.defaults()&&Object.keys(this.instance.defaults())}getDefaults(){return void 0!==this.instance.defaults&&"function"==typeof this.instance.defaults&&"object"==typeof this.instance.defaults()?this.instance.defaults():{}}processConfig(){const e=this.getDefaults();if(!1===this.acceptedConfigs)return e;for(const t in this.element.dataset)(!0===this.acceptedConfigs||this.acceptedConfigs.includes(t))&&(e[t]=this.coerceValue(this.element.dataset[t]));for(const t in this.localConfig)(!0===this.acceptedConfigs||this.acceptedConfigs.includes(t))&&(e[t]=this.localConfig[t]);return e}coerceValue(e){const t=String(e);if("null"===t)return null;if("undefined"!==t){if(t.startsWith("base64:")){const e=t.replace(/^base64:/,""),s=atob(e);return this.coerceValue(s)}if(["true","yes"].includes(t.toLowerCase()))return!0;if(["false","no"].includes(t.toLowerCase()))return!1;if(/^[-+]?[0-9]+(\.[0-9]+)?$/.test(t))return Number(t);try{return this.snowboard.jsonParser().parse(t)}catch(e){return""===t||t}}}}},336:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{construct(e,t,s){if(this.message=e,this.type=t||"default",this.duration=Number(s||7),this.duration<0)throw new Error("Flash duration must be a positive number, or zero");this.clear(),this.timer=null,this.flashTimer=null,this.create()}dependencies(){return["transition"]}destruct(){null!==this.timer&&window.clearTimeout(this.timer),this.flashTimer&&this.flashTimer.remove(),this.flash&&(this.flash.remove(),this.flash=null,this.flashTimer=null),super.destruct()}create(){this.snowboard.globalEvent("flash.create",this),this.flash=document.createElement("DIV"),this.flash.innerHTML=this.message,this.flash.classList.add("flash-message",this.type),this.flash.removeAttribute("data-control"),this.flash.addEventListener("click",(()=>this.remove())),this.flash.addEventListener("mouseover",(()=>this.stopTimer())),this.flash.addEventListener("mouseout",(()=>this.startTimer())),this.duration>0?(this.flashTimer=document.createElement("DIV"),this.flashTimer.classList.add("flash-timer"),this.flash.appendChild(this.flashTimer)):this.flash.classList.add("no-timer"),document.body.appendChild(this.flash),this.snowboard.transition(this.flash,"show",(()=>{this.startTimer()}))}remove(){this.snowboard.globalEvent("flash.remove",this),this.stopTimer(),this.snowboard.transition(this.flash,"hide",(()=>{this.flash.remove(),this.flash=null,this.destruct()}))}clear(){document.querySelectorAll("body > div.flash-message").forEach((e=>e.remove()))}startTimer(){0!==this.duration&&(this.timerTrans=this.snowboard.transition(this.flashTimer,"timeout",null,`${this.duration}.0s`,!0),this.timer=window.setTimeout((()=>this.remove()),1e3*this.duration))}stopTimer(){this.timerTrans&&this.timerTrans.cancel(),this.timer&&window.clearTimeout(this.timer)}}},758:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{dependencies(){return["request"]}listens(){return{ready:"ready",ajaxStart:"ajaxStart"}}ready(){this.counter=0,this.createStripe()}ajaxStart(e,t){!1!==t.options.stripe&&(this.show(),e.then((()=>{this.hide()})).catch((()=>{this.hide()})))}createStripe(){this.indicator=document.createElement("DIV"),this.stripe=document.createElement("DIV"),this.stripeLoaded=document.createElement("DIV"),this.indicator.classList.add("stripe-loading-indicator","loaded"),this.stripe.classList.add("stripe"),this.stripeLoaded.classList.add("stripe-loaded"),this.indicator.appendChild(this.stripe),this.indicator.appendChild(this.stripeLoaded),document.body.appendChild(this.indicator)}show(){this.counter+=1;const e=this.stripe.cloneNode(!0);this.indicator.appendChild(e),this.stripe.remove(),this.stripe=e,this.counter>1||(this.indicator.classList.remove("loaded"),document.body.classList.add("wn-loading"))}hide(e){this.counter-=1,!0===e&&(this.counter=0),this.counter<=0&&(this.indicator.classList.add("loaded"),document.body.classList.remove("wn-loading"))}}},75:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{listens(){return{ready:"ready"}}ready(){let e=!1;if(document.querySelectorAll('link[rel="stylesheet"]').forEach((t=>{t.href.endsWith("/modules/system/assets/css/snowboard.extras.css")&&(e=!0)})),!e){const e=document.createElement("link");e.setAttribute("rel","stylesheet"),e.setAttribute("href",this.snowboard.url().asset("/modules/system/assets/css/snowboard.extras.css")),document.head.appendChild(e)}}}},843:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{construct(e,t,s,n,i){if(e instanceof HTMLElement==!1)throw new Error("A HTMLElement must be provided for transitioning");if(this.element=e,"string"!=typeof t)throw new Error("Transition name must be specified as a string");if(this.transition=t,s&&"function"!=typeof s)throw new Error("Callback must be a valid function");this.callback=s,this.duration=n?this.parseDuration(n):null,this.trailTo=!0===i,this.doTransition()}eventClasses(){for(var e=arguments.length,t=new Array(e),s=0;s{const[s,n]=e;-1!==t.indexOf(s)&&i.push(n)})),i}doTransition(){null!==this.duration&&(this.element.style.transitionDuration=this.duration),this.resetClasses(),this.eventClasses("in","active").forEach((e=>{this.element.classList.add(e)})),window.requestAnimationFrame((()=>{"0s"!==window.getComputedStyle(this.element)["transition-duration"]?(this.element.addEventListener("transitionend",(()=>this.onTransitionEnd()),{once:!0}),window.requestAnimationFrame((()=>{this.element.classList.remove(this.eventClasses("in")[0]),this.element.classList.add(this.eventClasses("out")[0])}))):(this.resetClasses(),this.callback&&this.callback.apply(this.element),this.destruct())}))}onTransitionEnd(){this.eventClasses("active",this.trailTo?"":"out").forEach((e=>{this.element.classList.remove(e)})),this.callback&&this.callback.apply(this.element),null!==this.duration&&(this.element.style.transitionDuration=null),this.destruct()}cancel(){this.element.removeEventListener("transitionend",(()=>this.onTransitionEnd),{once:!0}),this.resetClasses(),null!==this.duration&&(this.element.style.transitionDuration=null),this.destruct()}resetClasses(){this.eventClasses().forEach((e=>{this.element.classList.remove(e)}))}parseDuration(e){const t=/^([0-9]+(\.[0-9]+)?)(m?s)?$/.exec(e),s=Number(t[1]);return"sec"===("s"===t[3]?"sec":"msec")?1e3*s+"ms":`${Math.floor(s)}ms`}}},54:function(e,t){t.A={get(e,t,s){if("string"==typeof t){const s=t.toLowerCase();if(e.hasPlugin(s))return function(){return Reflect.get(e,"plugins")[s].getInstance(...arguments)}}return Reflect.get(e,t,s)},has(e,t){if("string"==typeof t){const s=t.toLowerCase();if(e.hasPlugin(s))return!0}return Reflect.has(e,t)}}},160:function(e,t,s){s.d(t,{A:function(){return g}});var n=s(660),i=s(373),r={get(e,t,s){if("string"==typeof t){const s=t.toLowerCase();if(["attachAbstracts","loadUtilities","initialise","initialiseSingletons"].includes(t))throw new Error(`You cannot use the "${t}" Snowboard method within a plugin.`);if(e.hasPlugin(s))return function(){return Reflect.get(e,"plugins")[s].getInstance(...arguments)}}return Reflect.get(e,t,s)},has(e,t){if("string"==typeof t){const s=t.toLowerCase();if(["attachAbstracts","loadUtilities","initialise","initialiseSingletons"].includes(t))return!1;if(e.hasPlugin(s))return!0}return Reflect.has(e,t)}};class o{constructor(e,t,s){this.name=e,this.snowboard=new Proxy(t,r),this.instance=s,Object.freeze(this.instance),this.instances=[],this.singleton={initialised:!1},Object.seal(this.singleton),this.mocks={},this.originalFunctions={},Object.freeze(o.prototype),Object.freeze(this)}hasMethod(e){return!this.isFunction()&&"function"==typeof this.instance.prototype[e]}callMethod(){if(this.isFunction())return null;for(var e=arguments.length,t=new Array(e),s=0;s!this.snowboard.getPluginNames().includes(e)));throw new Error(`The "${this.name}" plugin requires the following plugins: ${e.join(", ")}`)}if(this.isSingleton())return 0===this.instances.length&&this.initialiseSingleton(...s),Object.keys(this.mocks).length>0&&(Object.entries(this.originalFunctions).forEach((e=>{const[t,s]=e;this.instances[0][t]=s})),Object.entries(this.mocks).forEach((t=>{const[s,n]=t;this.instances[0][s]=function(){for(var t=arguments.length,s=new Array(t),i=0;i0&&(Object.entries(this.originalFunctions).forEach((e=>{const[t,s]=e;this.instance.prototype[t]=s})),Object.entries(this.mocks).forEach((t=>{const[s,n]=t;this.instance.prototype[s]=function(){for(var t=arguments.length,s=new Array(t),i=0;ithis.instances.splice(this.instances.indexOf(i),1),i.construct(...s),this.instances.push(i),i}getInstances(){return this.isFunction()?[]:this.instances}isFunction(){return"function"==typeof this.instance&&this.instance.prototype instanceof n.A==!1}isSingleton(){return this.instance.prototype instanceof i.A==!0}isInitialised(){return!this.isSingleton()||this.singleton.initialised}initialiseSingleton(){if(!this.isSingleton())return;for(var e=arguments.length,t=new Array(e),s=0;sthis.instances.splice(this.instances.indexOf(n),1),n.construct(...t),this.instances.push(n),this.singleton.initialised=!0}getDependencies(){return this.isFunction()||"function"!=typeof this.instance.prototype.dependencies?[]:this.instance.prototype.dependencies().map((e=>e.toLowerCase()))}dependenciesFulfilled(){const e=this.getDependencies();let t=!0;return e.forEach((e=>{this.snowboard.hasPlugin(e)||(t=!1)})),t}mock(e,t){var s=this;if(!this.isFunction()){if(!this.instance.prototype[e])throw new Error(`Function "${e}" does not exist and cannot be mocked`);this.mocks[e]=t,this.originalFunctions[e]=this.instance.prototype[e],this.isSingleton()&&0===this.instances.length&&(this.initialiseSingleton(),this.instances[0][e]=function(){for(var e=arguments.length,n=new Array(e),i=0;i{const[t,s]=e;void 0!==this.defaults[t]&&(this.defaults[t]=s)}))}getDefaults(){const e={};return Object.entries(this.defaults).forEach((t=>{const[s,n]=t;null!==this.defaults[s]&&(e[s]=n)})),e}get(e){if(void 0===e){const e=a.A.get();return Object.entries(e).forEach((t=>{const[s,n]=t;this.snowboard.globalEvent("cookie.get",s,n,(t=>{e[s]=t}))})),e}let t=a.A.get(e);return this.snowboard.globalEvent("cookie.get",e,t,(e=>{t=e})),t}set(e,t,s){let n=t;return this.snowboard.globalEvent("cookie.set",e,t,(e=>{n=e})),a.A.set(e,n,h(h({},this.getDefaults()),s))}remove(e,t){a.A.remove(e,h(h({},this.getDefaults()),t))}}class u extends i.A{construct(){window.wnJSON=e=>this.parse(e),window.ocJSON=window.wnJSON}parse(e){const t=this.parseString(e);return JSON.parse(t)}parseString(e){let t=e.trim();if(!t.length)throw new Error("Broken JSON object.");let s="",n=null,i=null,r="";for(;t&&","===t[0];)t=t.substr(1);if('"'===t[0]||"'"===t[0]){if(t[t.length-1]!==t[0])throw new Error("Invalid string JSON object.");r='"';for(let e=1;e="0"&&e[t]<="9"){s="";for(let n=t;n="0"&&e[n]<="9"))return{originLength:s.length,body:s};s+=e[n]}throw new Error(`Broken JSON number body near ${s}`)}if("{"===e[t]||"["===e[t]){const n=[e[t]];s=e[t];for(let i=t+1;i=0?t-5:0,50)}`)}parseKey(e,t,s){let n="";for(let i=t;i="a"&&e[0]<="z"||e[0]>="A"&&e[0]<="Z"||"_"===e[0]||(e[0]>="0"&&e[0]<="9"||("$"===e[0]||e.charCodeAt(0)>255)))}isBlankChar(e){return" "===e||"\n"===e||"\t"===e}}class f extends i.A{construct(){window.wnSanitize=e=>this.sanitize(e),window.ocSanitize=window.wnSanitize}sanitize(e,t){const s=(new DOMParser).parseFromString(e,"text/html"),n=void 0===t||"boolean"!=typeof t||t;return this.sanitizeNode(s.getRootNode()),n?s.body.innerHTML:s.innerHTML}sanitizeNode(e){if("SCRIPT"===e.tagName)return void e.remove();this.trimAttributes(e);Array.from(e.children).forEach((e=>{this.sanitizeNode(e)}))}trimAttributes(e){if(e.attributes)for(let t=0;t{this.autoInitSingletons&&this.initialiseSingletons(),this.globalEvent("ready"),this.readiness.dom=!0}))}initialiseSingletons(){Object.values(this.plugins).forEach((e=>{e.isSingleton()&&e.dependenciesFulfilled()&&e.initialiseSingleton()}))}addPlugin(e,t){const s=e.toLowerCase();if(this.hasPlugin(s))throw new Error(`A plugin called "${e}" is already registered.`);if("function"!=typeof t&&t instanceof n.A==!1)throw new Error("The provided plugin must extend the PluginBase class, or must be a callback function.");if(void 0!==this[e]||void 0!==this[s])throw new Error("The given name is already in use for a property or method of the Snowboard class.");this.plugins[s]=new o(s,this,t),this.debug(`Plugin "${e}" registered`),Object.values(this.getPlugins()).forEach((e=>{if(e.isSingleton()&&!e.isInitialised()&&e.dependenciesFulfilled()&&e.hasMethod("listens")&&Object.keys(e.callMethod("listens")).includes("ready")&&this.readiness.dom){const t=e.callMethod("listens").ready;e.callMethod(t)}}))}removePlugin(e){const t=e.toLowerCase();this.hasPlugin(t)?(this.plugins[t].getInstances().forEach((e=>{e.destruct()})),delete this.plugins[t],delete this[t],delete this[e],this.debug(`Plugin "${e}" removed`)):this.debug(`Plugin "${e}" already removed`)}hasPlugin(e){const t=e.toLowerCase();return void 0!==this.plugins[t]}getPlugins(){return this.plugins}getPluginNames(){return Object.keys(this.plugins)}getPlugin(e){const t=e.toLowerCase();if(!this.hasPlugin(t))throw new Error(`No plugin called "${t}" has been registered.`);return this.plugins[t]}listensToEvent(e){const t=[];return Object.entries(this.plugins).forEach((s=>{const[n,i]=s;if(i.isFunction())return;if(!i.dependenciesFulfilled())return;if(!i.hasMethod("listens"))return;const r=i.callMethod("listens");"string"!=typeof r[e]&&"function"!=typeof r[e]||t.push(n)})),t}ready(e){this.readiness.dom&&e(),this.on("ready",e)}on(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].includes(t)||this.listeners[e].push(t)}off(e,t){if(!this.listeners[e])return;const s=this.listeners[e].indexOf(t);-1!==s&&this.listeners[e].splice(s,1)}globalEvent(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n{const n=this.getPlugin(t);if(n.isFunction())return;n.isSingleton()&&0===n.getInstances().length&&n.initialiseSingleton();const i=n.callMethod("listens")[e];n.getInstances().forEach((n=>{if(!r)if("function"==typeof i)try{!1===i.apply(n,s)&&(r=!0)}catch(s){this.error(`Error thrown in "${e}" event by "${t}" plugin.`,s)}else if("string"==typeof i){if(!n[i])throw new Error(`Missing "${i}" method in "${t}" plugin`);try{!1===n[i](...s)&&(r=!0,this.debug(`Global event "${e}" cancelled by "${t}" plugin`))}catch(s){this.error(`Error thrown in "${e}" event by "${t}" plugin.`,s)}}else this.error(`Listen method for "${e}" event in "${t}" plugin is not a function or string.`)}))})),!r&&this.listeners[e]&&this.listeners[e].length>0&&(this.debug(`Found ${this.listeners[e].length} ad-hoc listener(s) for global event "${e}"`),this.listeners[e].forEach((t=>{if(!r)try{!1===t(...s)&&(r=!0,this.debug(`Global event "${e} cancelled by an ad-hoc listener.`))}catch(t){this.error(`Error thrown in "${e}" event by an ad-hoc listener.`,t)}}))),!r}globalPromiseEvent(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n{const n=this.getPlugin(t);if(n.isFunction())return;n.isSingleton()&&0===n.getInstances().length&&n.initialiseSingleton();const i=n.callMethod("listens")[e];n.getInstances().forEach((n=>{if("function"==typeof i)try{const e=i.apply(n,s);if(e instanceof Promise==!1)return;r.push(e)}catch(s){this.error(`Error thrown in "${e}" event by "${t}" plugin.`,s)}else if("string"==typeof i){if(!n[i])throw new Error(`Missing "${i}" method in "${t}" plugin`);try{const e=n[i](...s);if(e instanceof Promise==!1)return;r.push(e)}catch(s){this.error(`Error thrown in "${e}" promise event by "${t}" plugin.`,s)}}else this.error(`Listen method for "${e}" event in "${t}" plugin is not a function or string.`)}))})),this.listeners[e]&&this.listeners[e].length>0&&(this.debug(`Found ${this.listeners[e].length} ad-hoc listener(s) for global promise event "${e}"`),this.listeners[e].forEach((t=>{try{const e=t(...s);if(e instanceof Promise==!1)return;r.push(e)}catch(t){this.error(`Error thrown in "${e}" promise event by an ad-hoc listener.`,t)}}))),0===r.length?Promise.resolve():Promise.all(r)}logMessage(e,t,s){console.groupCollapsed("%c[Snowboard]",`color: ${e}; font-weight: ${t?"bold":"normal"};`,s);for(var n=arguments.length,i=new Array(n>3?n-3:0),r=3;r{e+=1,console.log(`%c${e}:`,"color: rgb(88, 88, 88); font-weight: normal;",t)})),console.groupEnd(),console.groupCollapsed("%cTrace","color: rgb(45, 167, 199); font-weight: bold;"),console.trace(),console.groupEnd()}else console.trace();console.groupEnd()}log(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n1?t-1:0),n=1;n1?t-1:0),n=1;n{const t=new Proxy(new n.A,i.A);e.snowboard=t,e.Snowboard=t,e.SnowBoard=t})(window)},59:function(e,t,s){var n=s(660);function i(e,t){var s=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),s.push.apply(s,n)}return s}function r(e){for(var t=1;t{e&&this.doAjax().then((e=>{if(e.cancelled)return this.cancelled=!0,void this.complete();this.responseData=e,this.processUpdate(e).then((()=>{!1===e.X_WINTER_SUCCESS?this.processError(e):this.processResponse(e)}))}),(e=>{this.responseError=e,this.processError(e)}))})):this.doAjax().then((e=>{if(e.cancelled)return this.cancelled=!0,void this.complete();this.responseData=e,this.processUpdate(e).then((()=>{!1===e.X_WINTER_SUCCESS?this.processError(e):this.processResponse(e)}))}),(e=>{this.responseError=e,this.processError(e)})):this.cancelled=!0}else this.cancelled=!0}dependencies(){return["cookie","jsonParser"]}checkRequest(){if(this.element&&this.element instanceof Element==!1)throw new Error("The element provided must be an Element instance");if(void 0===this.handler)throw new Error("The AJAX handler name is not specified.");if(!this.isHandlerName(this.handler))throw new Error('Invalid AJAX handler name. The correct handler name format is: "onEvent".')}getFetch(){return this.fetchOptions=void 0!==this.options.fetchOptions&&"object"==typeof this.options.fetchOptions?this.options.fetchOptions:{method:"POST",headers:this.headers,body:this.data,redirect:"follow",mode:"same-origin"},this.snowboard.globalEvent("ajaxFetchOptions",this.fetchOptions,this),fetch(this.url,this.fetchOptions)}doClientValidation(){return!0!==this.options.browserValidate||!this.form||!1!==this.form.checkValidity()||(this.form.reportValidity(),!1)}doAjax(){if(!1===this.snowboard.globalEvent("ajaxBeforeSend",this))return Promise.resolve({cancelled:!0});const e=new Promise(((e,t)=>{this.getFetch().then((s=>{s.ok||406===s.status?s.headers.has("Content-Type")&&s.headers.get("Content-Type").includes("/json")?s.json().then((t=>{e(r(r({},t),{},{X_WINTER_SUCCESS:406!==s.status,X_WINTER_RESPONSE_CODE:s.status}))}),(e=>{t(this.renderError(`Unable to parse JSON response: ${e}`))})):s.text().then((t=>{e(t)}),(e=>{t(this.renderError(`Unable to process response: ${e}`))})):s.headers.has("Content-Type")&&s.headers.get("Content-Type").includes("/json")?s.json().then((e=>{e.message&&e.exception?t(this.renderError(e.message,e.exception,e.file,e.line,e.trace)):t(e)}),(e=>{t(this.renderError(`Unable to parse JSON response: ${e}`))})):s.text().then((e=>{t(this.renderError(e))}),(e=>{t(this.renderError(`Unable to process response: ${e}`))}))}),(e=>{t(this.renderError(`Unable to retrieve a response from the server: ${e}`))}))}));if(this.snowboard.globalEvent("ajaxStart",e,this),this.element){const t=new Event("ajaxPromise");t.promise=e,this.element.dispatchEvent(t)}return e}processUpdate(e){return new Promise(((t,s)=>{if("function"==typeof this.options.beforeUpdate&&!1===this.options.beforeUpdate.apply(this,[e]))return void t();const n={};if(Object.entries(e).forEach((e=>{const[t,s]=e;"X_WINTER"!==t.substr(0,8)&&(n[t]=s)})),0===Object.keys(n).length)return void(e.X_WINTER_ASSETS?this.processAssets(e.X_WINTER_ASSETS).then((()=>{t()}),(()=>{s()})):t());this.snowboard.globalPromiseEvent("ajaxBeforeUpdate",e,this).then((async()=>{e.X_WINTER_ASSETS&&await this.processAssets(e.X_WINTER_ASSETS),this.doUpdate(n).then((()=>{window.requestAnimationFrame((()=>t()))}),(()=>{s()}))}),(()=>{t()}))}))}doUpdate(e){return new Promise((t=>{const s=[];Object.entries(e).forEach((e=>{const[t,n]=e;let i=this.options.update&&this.options.update[t]?this.options.update[t]:t,r="replace";"@"===i.substr(0,1)?(r="append",i=i.substr(1)):"^"===i.substr(0,1)?(r="prepend",i=i.substr(1)):"#"!==i.substr(0,1)&&"."!==i.substr(0,1)&&(r="noop");const o=document.querySelectorAll(i);o.length>0&&o.forEach((e=>{switch(r){case"append":e.innerHTML+=n;break;case"prepend":e.innerHTML=n+e.innerHTML;break;case"noop":break;default:e.innerHTML=n}s.push(e),this.snowboard.globalEvent("ajaxUpdate",e,n,this);const t=new Event("ajaxUpdate");t.content=n,e.dispatchEvent(t)}))})),this.snowboard.globalEvent("ajaxUpdateComplete",s,this),t()}))}processResponse(e){if((!this.options.success||"function"!=typeof this.options.success||!1!==this.options.success(this.responseData,this))&&!1!==this.snowboard.globalEvent("ajaxSuccess",this.responseData,this)){if(this.element){const e=new Event("ajaxDone",{cancelable:!0});if(e.responseData=this.responseData,e.request=this,this.element.dispatchEvent(e),e.defaultPrevented)return}this.flash&&e.X_WINTER_FLASH_MESSAGES&&this.processFlashMessages(e.X_WINTER_FLASH_MESSAGES),this.redirect||e.X_WINTER_REDIRECT?this.processRedirect(this.redirect||e.X_WINTER_REDIRECT):this.complete()}}processError(e){if((!this.options.error||"function"!=typeof this.options.error||!1!==this.options.error(this.responseError,this))&&!1!==this.snowboard.globalEvent("ajaxError",this.responseError,this)){if(this.element){const e=new Event("ajaxFail",{cancelable:!0});if(e.responseError=this.responseError,e.request=this,this.element.dispatchEvent(e),e.defaultPrevented)return}if(e instanceof Error)this.processErrorMessage(e.message);else{let t=!1;e.X_WINTER_ERROR_FIELDS&&(t=this.processValidationErrors(e.X_WINTER_ERROR_FIELDS)),e.X_WINTER_ERROR_MESSAGE&&!t&&this.processErrorMessage(e.X_WINTER_ERROR_MESSAGE)}this.complete()}}processRedirect(e){"function"==typeof this.options.handleRedirectResponse&&!1===this.options.handleRedirectResponse.apply(this,[e])||!1!==this.snowboard.globalEvent("ajaxRedirect",e,this)&&(window.addEventListener("popstate",(()=>{if(this.element){const e=document.createEvent("CustomEvent");e.eventName="ajaxRedirected",this.element.dispatchEvent(e)}}),{once:!0}),window.location.assign(e))}processErrorMessage(e){"function"==typeof this.options.handleErrorMessage&&!1===this.options.handleErrorMessage.apply(this,[e])||!1!==this.snowboard.globalEvent("ajaxErrorMessage",e,this)&&window.alert(e)}processFlashMessages(e){"function"==typeof this.options.handleFlashMessages&&!1===this.options.handleFlashMessages.apply(this,[e])||this.snowboard.globalEvent("ajaxFlashMessages",e,this)}processValidationErrors(e){return"function"==typeof this.options.handleValidationErrors&&!1===this.options.handleValidationErrors.apply(this,[this.form,e])||!1===this.snowboard.globalEvent("ajaxValidationErrors",this.form,e,this)}processAssets(e){return this.snowboard.globalPromiseEvent("ajaxLoadAssets",e)}async doConfirm(){if("function"==typeof this.options.handleConfirmMessage)return!1!==this.options.handleConfirmMessage.apply(this,[this.confirm]);if(0===this.snowboard.listensToEvent("ajaxConfirmMessage").length)return window.confirm(this.confirm);const e=this.snowboard.globalPromiseEvent("ajaxConfirmMessage",this.confirm,this);try{if(await e)return!0}catch(e){return!1}return!1}complete(){if(this.options.complete&&"function"==typeof this.options.complete&&this.options.complete(this.responseData,this),this.snowboard.globalEvent("ajaxDone",this.responseData,this),this.element){const e=new Event("ajaxAlways");e.request=this,e.responseData=this.responseData,e.responseError=this.responseError,this.element.dispatchEvent(e)}this.destruct()}get form(){return this.options.form?"string"==typeof this.options.form?document.querySelector(this.options.form):this.options.form:this.element?"FORM"===this.element.tagName?this.element:this.element.closest("form"):null}get context(){return{handler:this.handler,options:this.options}}get headers(){const e={"X-Requested-With":"XMLHttpRequest","X-WINTER-REQUEST-HANDLER":this.handler,"X-WINTER-REQUEST-PARTIALS":this.extractPartials(this.options.update||[])};return this.flash&&(e["X-WINTER-REQUEST-FLASH"]=1),this.xsrfToken&&(e["X-XSRF-TOKEN"]=this.xsrfToken),e}get loading(){return this.options.loading||!1}get url(){return this.options.url||window.location.href}get redirect(){return this.options.redirect&&this.options.redirect.length?this.options.redirect:null}get flash(){return this.options.flash||!1}get files(){return!0===this.options.files&&(void 0!==FormData||(this.snowboard.debug("This browser does not support file uploads"),!1))}get xsrfToken(){return this.snowboard.cookie().get("XSRF-TOKEN")}get data(){const e="object"==typeof this.options.data?this.options.data:{},t=new FormData(this.form||void 0);return Object.keys(e).length>0&&this.createFormData(t,e),t}createFormData(e,t){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";"object"==typeof t?Array.isArray(t)&&""!==s?t.forEach((t=>{this.createFormData(e,t,`${s}[]`)})):Object.entries(t).forEach((t=>{const[n,i]=t;this.createFormData(e,i,""!==s?`${s}[${n}]`:n)})):e.append(s,t)}get confirm(){return this.options.confirm||!1}extractPartials(e){return Object.keys(e).join("&")}renderError(e,t,s,n,i){const r=new Error(e);return r.exception=t||null,r.file=s||null,r.line=n||null,r.trace=i||[],r}isHandlerName(e){return/^(?:\w+:{2})?on[A-Z0-9]/.test(e)}}if(void 0===window.Snowboard)throw new Error("Snowboard must be loaded in order to use the Javascript AJAX request feature.");window.Snowboard.addPlugin("request",a)},557:function(){},740:function(){},48:function(){},27:function(){},730:function(){},909:function(){}},function(e){var t=function(t){return e(e.s=t)};e.O(0,[969,778,321,955,71,261,214],(function(){return t(2),t(59),t(590),t(740),t(48),t(27),t(730),t(909),t(557)}));e.O()}]); \ No newline at end of file +"use strict";(self.webpackChunk_wintercms_wn_system_module=self.webpackChunk_wintercms_wn_system_module||[]).push([[336,861,813],{660:function(e,t,s){s.d(t,{A:function(){return n}});class n{constructor(e){this.snowboard=e}construct(){}dependencies(){return[]}listens(){return{}}destruct(){this.detach(),delete this.snowboard}destructor(){this.destruct()}}},373:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{}},477:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{listens(){return{ajaxLoadAssets:"load"}}dependencies(){return["url"]}async load(e){if(e.js&&e.js.length>0)for(const t of e.js)try{await this.loadScript(t)}catch(e){return Promise.reject(e)}if(e.css&&e.css.length>0)for(const t of e.css)try{await this.loadStyle(t)}catch(e){return Promise.reject(e)}if(e.img&&e.img.length>0)for(const t of e.img)try{await this.loadImage(t)}catch(e){return Promise.reject(e)}return Promise.resolve()}loadScript(e){return new Promise(((t,s)=>{e=this.snowboard.url().asset(e);if(document.querySelector(`script[src="${e}"]`))return void t();const n=document.createElement("script");n.setAttribute("type","text/javascript"),n.setAttribute("src",e),n.addEventListener("load",(()=>{this.snowboard.globalEvent("assetLoader.loaded","script",e,n),t()})),n.addEventListener("error",(()=>{this.snowboard.globalEvent("assetLoader.error","script",e,n),s(new Error(`Unable to load script file: "${e}"`))})),document.body.append(n)}))}loadStyle(e){return new Promise(((t,s)=>{e=this.snowboard.url().asset(e);if(document.querySelector(`link[rel="stylesheet"][href="${e}"]`))return void t();const n=document.createElement("link");n.setAttribute("rel","stylesheet"),n.setAttribute("href",e),n.addEventListener("load",(()=>{this.snowboard.globalEvent("assetLoader.loaded","style",e,n),t()})),n.addEventListener("error",(()=>{this.snowboard.globalEvent("assetLoader.error","style",e,n),s(new Error(`Unable to load stylesheet file: "${e}"`))})),document.head.append(n)}))}loadImage(e){return new Promise(((t,s)=>{e=this.snowboard.url().asset(e);const n=new Image;n.addEventListener("load",(()=>{this.snowboard.globalEvent("assetLoader.loaded","image",e,n),t()})),n.addEventListener("error",(()=>{this.snowboard.globalEvent("assetLoader.error","image",e,n),s(new Error(`Unable to load image file: "${e}"`))})),n.src=e}))}}},293:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{dependencies(){return["request"]}listens(){return{ajaxStart:"ajaxStart",ajaxDone:"ajaxDone"}}ajaxStart(e,t){if(t.element)if("FORM"===t.element.tagName){const e=t.element.querySelectorAll("[data-attach-loading]");e.length>0&&e.forEach((e=>{e.classList.add(this.getLoadingClass(e))}))}else void 0!==t.element.dataset.attachLoading&&t.element.classList.add(this.getLoadingClass(t.element))}ajaxDone(e,t){if(t.element)if("FORM"===t.element.tagName){const e=t.element.querySelectorAll("[data-attach-loading]");e.length>0&&e.forEach((e=>{e.classList.remove(this.getLoadingClass(e))}))}else void 0!==t.element.dataset.attachLoading&&t.element.classList.remove(this.getLoadingClass(t.element))}getLoadingClass(e){return void 0!==e.dataset.attachLoading&&""!==e.dataset.attachLoading?e.dataset.attachLoading:"wn-loading"}}},490:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{construct(e,t,s){if(e instanceof n.A==!1)throw new Error("You must provide a Snowboard plugin to enable data configuration");if(t instanceof HTMLElement==!1)throw new Error("Data configuration can only be extracted from HTML elements");this.instance=e,this.element=t,this.localConfig=s||{},this.instanceConfig={},this.acceptedConfigs={},this.refresh()}get(e){return void 0===e?this.instanceConfig:void 0!==this.instanceConfig[e]?this.instanceConfig[e]:void 0}set(e,t,s){if(void 0===e)throw new Error("You must provide a configuration key to set");this.instanceConfig[e]=t,!0===s&&(this.element.dataset[e]=t,this.localConfig[e]=t)}refresh(){this.acceptedConfigs=this.getAcceptedConfigs(),this.instanceConfig=this.processConfig()}getAcceptedConfigs(){return void 0!==this.instance.acceptAllDataConfigs&&!0===this.instance.acceptAllDataConfigs||void 0!==this.instance.defaults&&"function"==typeof this.instance.defaults&&"object"==typeof this.instance.defaults()&&Object.keys(this.instance.defaults())}getDefaults(){return void 0!==this.instance.defaults&&"function"==typeof this.instance.defaults&&"object"==typeof this.instance.defaults()?this.instance.defaults():{}}processConfig(){const e=this.getDefaults();if(!1===this.acceptedConfigs)return e;for(const t in this.element.dataset)(!0===this.acceptedConfigs||this.acceptedConfigs.includes(t))&&(e[t]=this.coerceValue(this.element.dataset[t]));for(const t in this.localConfig)(!0===this.acceptedConfigs||this.acceptedConfigs.includes(t))&&(e[t]=this.localConfig[t]);return e}coerceValue(e){const t=String(e);if("null"===t)return null;if("undefined"!==t){if(t.startsWith("base64:")){const e=t.replace(/^base64:/,""),s=atob(e);return this.coerceValue(s)}if(["true","yes"].includes(t.toLowerCase()))return!0;if(["false","no"].includes(t.toLowerCase()))return!1;if(/^[-+]?[0-9]+(\.[0-9]+)?$/.test(t))return Number(t);try{return this.snowboard.jsonParser().parse(t)}catch(e){return""===t||t}}}}},336:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{construct(e,t,s){if(this.message=e,this.type=t||"default",this.duration=Number(s||7),this.duration<0)throw new Error("Flash duration must be a positive number, or zero");this.clear(),this.timer=null,this.flashTimer=null,this.create()}dependencies(){return["transition"]}destruct(){null!==this.timer&&window.clearTimeout(this.timer),this.flashTimer&&this.flashTimer.remove(),this.flash&&(this.flash.remove(),this.flash=null,this.flashTimer=null),super.destruct()}create(){this.snowboard.globalEvent("flash.create",this),this.flash=document.createElement("DIV"),this.flash.innerHTML=this.message,this.flash.classList.add("flash-message",this.type),this.flash.removeAttribute("data-control"),this.flash.addEventListener("click",(()=>this.remove())),this.flash.addEventListener("mouseover",(()=>this.stopTimer())),this.flash.addEventListener("mouseout",(()=>this.startTimer())),this.duration>0?(this.flashTimer=document.createElement("DIV"),this.flashTimer.classList.add("flash-timer"),this.flash.appendChild(this.flashTimer)):this.flash.classList.add("no-timer"),document.body.appendChild(this.flash),this.snowboard.transition(this.flash,"show",(()=>{this.startTimer()}))}remove(){this.snowboard.globalEvent("flash.remove",this),this.stopTimer(),this.snowboard.transition(this.flash,"hide",(()=>{this.flash.remove(),this.flash=null,this.destruct()}))}clear(){document.querySelectorAll("body > div.flash-message").forEach((e=>e.remove()))}startTimer(){0!==this.duration&&(this.timerTrans=this.snowboard.transition(this.flashTimer,"timeout",null,`${this.duration}.0s`,!0),this.timer=window.setTimeout((()=>this.remove()),1e3*this.duration))}stopTimer(){this.timerTrans&&this.timerTrans.cancel(),this.timer&&window.clearTimeout(this.timer)}}},758:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{dependencies(){return["request"]}listens(){return{ready:"ready",ajaxStart:"ajaxStart"}}ready(){this.counter=0,this.createStripe()}ajaxStart(e,t){!1!==t.options.stripe&&(this.show(),e.then((()=>{this.hide()})).catch((()=>{this.hide()})))}createStripe(){this.indicator=document.createElement("DIV"),this.stripe=document.createElement("DIV"),this.stripeLoaded=document.createElement("DIV"),this.indicator.classList.add("stripe-loading-indicator","loaded"),this.stripe.classList.add("stripe"),this.stripeLoaded.classList.add("stripe-loaded"),this.indicator.appendChild(this.stripe),this.indicator.appendChild(this.stripeLoaded),document.body.appendChild(this.indicator)}show(){this.counter+=1;const e=this.stripe.cloneNode(!0);this.indicator.appendChild(e),this.stripe.remove(),this.stripe=e,this.counter>1||(this.indicator.classList.remove("loaded"),document.body.classList.add("wn-loading"))}hide(e){this.counter-=1,!0===e&&(this.counter=0),this.counter<=0&&(this.indicator.classList.add("loaded"),document.body.classList.remove("wn-loading"))}}},75:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(373);class i extends n.A{listens(){return{ready:"ready"}}ready(){let e=!1;if(document.querySelectorAll('link[rel="stylesheet"]').forEach((t=>{t.href.endsWith("/modules/system/assets/css/snowboard.extras.css")&&(e=!0)})),!e){const e=document.createElement("link");e.setAttribute("rel","stylesheet"),e.setAttribute("href",this.snowboard.url().asset("/modules/system/assets/css/snowboard.extras.css")),document.head.appendChild(e)}}}},843:function(e,t,s){s.d(t,{A:function(){return i}});var n=s(660);class i extends n.A{construct(e,t,s,n,i){if(e instanceof HTMLElement==!1)throw new Error("A HTMLElement must be provided for transitioning");if(this.element=e,"string"!=typeof t)throw new Error("Transition name must be specified as a string");if(this.transition=t,s&&"function"!=typeof s)throw new Error("Callback must be a valid function");this.callback=s,this.duration=n?this.parseDuration(n):null,this.trailTo=!0===i,this.doTransition()}eventClasses(){for(var e=arguments.length,t=new Array(e),s=0;s{const[s,n]=e;-1!==t.indexOf(s)&&i.push(n)})),i}doTransition(){null!==this.duration&&(this.element.style.transitionDuration=this.duration),this.resetClasses(),this.eventClasses("in","active").forEach((e=>{this.element.classList.add(e)})),window.requestAnimationFrame((()=>{"0s"!==window.getComputedStyle(this.element)["transition-duration"]?(this.element.addEventListener("transitionend",(()=>this.onTransitionEnd()),{once:!0}),window.requestAnimationFrame((()=>{this.element.classList.remove(this.eventClasses("in")[0]),this.element.classList.add(this.eventClasses("out")[0])}))):(this.resetClasses(),this.callback&&this.callback.apply(this.element),this.destruct())}))}onTransitionEnd(){this.eventClasses("active",this.trailTo?"":"out").forEach((e=>{this.element.classList.remove(e)})),this.callback&&this.callback.apply(this.element),null!==this.duration&&(this.element.style.transitionDuration=null),this.destruct()}cancel(){this.element.removeEventListener("transitionend",(()=>this.onTransitionEnd),{once:!0}),this.resetClasses(),null!==this.duration&&(this.element.style.transitionDuration=null),this.destruct()}resetClasses(){this.eventClasses().forEach((e=>{this.element.classList.remove(e)}))}parseDuration(e){const t=/^([0-9]+(\.[0-9]+)?)(m?s)?$/.exec(e),s=Number(t[1]);return"sec"===("s"===t[3]?"sec":"msec")?1e3*s+"ms":`${Math.floor(s)}ms`}}},54:function(e,t){t.A={get(e,t,s){if("string"==typeof t){const s=t.toLowerCase();if(e.hasPlugin(s))return function(){return Reflect.get(e,"plugins")[s].getInstance(...arguments)}}return Reflect.get(e,t,s)},has(e,t){if("string"==typeof t){const s=t.toLowerCase();if(e.hasPlugin(s))return!0}return Reflect.has(e,t)}}},160:function(e,t,s){s.d(t,{A:function(){return g}});var n=s(660),i=s(373),r={get(e,t,s){if("string"==typeof t){const s=t.toLowerCase();if(["attachAbstracts","loadUtilities","initialise","initialiseSingletons"].includes(t))throw new Error(`You cannot use the "${t}" Snowboard method within a plugin.`);if(e.hasPlugin(s))return function(){return Reflect.get(e,"plugins")[s].getInstance(...arguments)}}return Reflect.get(e,t,s)},has(e,t){if("string"==typeof t){const s=t.toLowerCase();if(["attachAbstracts","loadUtilities","initialise","initialiseSingletons"].includes(t))return!1;if(e.hasPlugin(s))return!0}return Reflect.has(e,t)}};class o{constructor(e,t,s){this.name=e,this.snowboard=new Proxy(t,r),this.instance=s,Object.freeze(this.instance),this.instances=[],this.singleton={initialised:!1},Object.seal(this.singleton),this.mocks={},this.originalFunctions={},Object.freeze(o.prototype),Object.freeze(this)}hasMethod(e){return!this.isFunction()&&"function"==typeof this.instance.prototype[e]}callMethod(){if(this.isFunction())return null;for(var e=arguments.length,t=new Array(e),s=0;s!this.snowboard.getPluginNames().includes(e)));throw new Error(`The "${this.name}" plugin requires the following plugins: ${e.join(", ")}`)}if(this.isSingleton())return 0===this.instances.length&&this.initialiseSingleton(...s),Object.keys(this.mocks).length>0&&(Object.entries(this.originalFunctions).forEach((e=>{const[t,s]=e;this.instances[0][t]=s})),Object.entries(this.mocks).forEach((t=>{const[s,n]=t;this.instances[0][s]=function(){for(var t=arguments.length,s=new Array(t),i=0;i0&&(Object.entries(this.originalFunctions).forEach((e=>{const[t,s]=e;this.instance.prototype[t]=s})),Object.entries(this.mocks).forEach((t=>{const[s,n]=t;this.instance.prototype[s]=function(){for(var t=arguments.length,s=new Array(t),i=0;ithis.instances.splice(this.instances.indexOf(i),1),i.construct(...s),this.instances.push(i),i}getInstances(){return this.isFunction()?[]:this.instances}isFunction(){return"function"==typeof this.instance&&this.instance.prototype instanceof n.A==!1}isSingleton(){return this.instance.prototype instanceof i.A==!0}isInitialised(){return!this.isSingleton()||this.singleton.initialised}initialiseSingleton(){if(!this.isSingleton())return;for(var e=arguments.length,t=new Array(e),s=0;sthis.instances.splice(this.instances.indexOf(n),1),n.construct(...t),this.instances.push(n),this.singleton.initialised=!0}getDependencies(){return this.isFunction()||"function"!=typeof this.instance.prototype.dependencies?[]:this.instance.prototype.dependencies().map((e=>e.toLowerCase()))}dependenciesFulfilled(){const e=this.getDependencies();let t=!0;return e.forEach((e=>{this.snowboard.hasPlugin(e)||(t=!1)})),t}mock(e,t){var s=this;if(!this.isFunction()){if(!this.instance.prototype[e])throw new Error(`Function "${e}" does not exist and cannot be mocked`);this.mocks[e]=t,this.originalFunctions[e]=this.instance.prototype[e],this.isSingleton()&&0===this.instances.length&&(this.initialiseSingleton(),this.instances[0][e]=function(){for(var e=arguments.length,n=new Array(e),i=0;i{const[t,s]=e;void 0!==this.defaults[t]&&(this.defaults[t]=s)}))}getDefaults(){const e={};return Object.entries(this.defaults).forEach((t=>{const[s,n]=t;null!==this.defaults[s]&&(e[s]=n)})),e}get(e){if(void 0===e){const e=a.A.get();return Object.entries(e).forEach((t=>{const[s,n]=t;this.snowboard.globalEvent("cookie.get",s,n,(t=>{e[s]=t}))})),e}let t=a.A.get(e);return this.snowboard.globalEvent("cookie.get",e,t,(e=>{t=e})),t}set(e,t,s){let n=t;return this.snowboard.globalEvent("cookie.set",e,t,(e=>{n=e})),a.A.set(e,n,h(h({},this.getDefaults()),s))}remove(e,t){a.A.remove(e,h(h({},this.getDefaults()),t))}}class u extends i.A{construct(){window.wnJSON=e=>this.parse(e),window.ocJSON=window.wnJSON}parse(e){const t=this.parseString(e);return JSON.parse(t)}parseString(e){let t=e.trim();if(!t.length)throw new Error("Broken JSON object.");let s="",n=null,i=null,r="";for(;t&&","===t[0];)t=t.substr(1);if('"'===t[0]||"'"===t[0]){if(t[t.length-1]!==t[0])throw new Error("Invalid string JSON object.");r='"';for(let e=1;e="0"&&e[t]<="9"){s="";for(let n=t;n="0"&&e[n]<="9"))return{originLength:s.length,body:s};s+=e[n]}throw new Error(`Broken JSON number body near ${s}`)}if("{"===e[t]||"["===e[t]){const n=[e[t]];s=e[t];for(let i=t+1;i=0?t-5:0,50)}`)}parseKey(e,t,s){let n="";for(let i=t;i="a"&&e[0]<="z"||e[0]>="A"&&e[0]<="Z"||"_"===e[0]||(e[0]>="0"&&e[0]<="9"||("$"===e[0]||e.charCodeAt(0)>255)))}isBlankChar(e){return" "===e||"\n"===e||"\t"===e}}class f extends i.A{construct(){window.wnSanitize=e=>this.sanitize(e),window.ocSanitize=window.wnSanitize}sanitize(e,t){const s=(new DOMParser).parseFromString(e,"text/html"),n=void 0===t||"boolean"!=typeof t||t;return this.sanitizeNode(s.getRootNode()),n?s.body.innerHTML:s.innerHTML}sanitizeNode(e){if("SCRIPT"===e.tagName)return void e.remove();this.trimAttributes(e);Array.from(e.children).forEach((e=>{this.sanitizeNode(e)}))}trimAttributes(e){if(e.attributes)for(let t=0;t{this.autoInitSingletons&&this.initialiseSingletons(),this.globalEvent("ready"),this.readiness.dom=!0}))}initialiseSingletons(){Object.values(this.plugins).forEach((e=>{e.isSingleton()&&e.dependenciesFulfilled()&&e.initialiseSingleton()}))}addPlugin(e,t){const s=e.toLowerCase();if(this.hasPlugin(s))throw new Error(`A plugin called "${e}" is already registered.`);if("function"!=typeof t&&t instanceof n.A==!1)throw new Error("The provided plugin must extend the PluginBase class, or must be a callback function.");if(void 0!==this[e]||void 0!==this[s])throw new Error("The given name is already in use for a property or method of the Snowboard class.");this.plugins[s]=new o(s,this,t),this.debug(`Plugin "${e}" registered`),Object.values(this.getPlugins()).forEach((e=>{if(e.isSingleton()&&!e.isInitialised()&&e.dependenciesFulfilled()&&e.hasMethod("listens")&&Object.keys(e.callMethod("listens")).includes("ready")&&this.readiness.dom){const t=e.callMethod("listens").ready;e.callMethod(t)}}))}removePlugin(e){const t=e.toLowerCase();this.hasPlugin(t)?(this.plugins[t].getInstances().forEach((e=>{e.destruct()})),delete this.plugins[t],delete this[t],delete this[e],this.debug(`Plugin "${e}" removed`)):this.debug(`Plugin "${e}" already removed`)}hasPlugin(e){const t=e.toLowerCase();return void 0!==this.plugins[t]}getPlugins(){return this.plugins}getPluginNames(){return Object.keys(this.plugins)}getPlugin(e){const t=e.toLowerCase();if(!this.hasPlugin(t))throw new Error(`No plugin called "${t}" has been registered.`);return this.plugins[t]}listensToEvent(e){const t=[];return Object.entries(this.plugins).forEach((s=>{const[n,i]=s;if(i.isFunction())return;if(!i.dependenciesFulfilled())return;if(!i.hasMethod("listens"))return;const r=i.callMethod("listens");"string"!=typeof r[e]&&"function"!=typeof r[e]||t.push(n)})),t}ready(e){this.readiness.dom&&e(),this.on("ready",e)}on(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].includes(t)||this.listeners[e].push(t)}off(e,t){if(!this.listeners[e])return;const s=this.listeners[e].indexOf(t);-1!==s&&this.listeners[e].splice(s,1)}globalEvent(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n{const n=this.getPlugin(t);if(n.isFunction())return;n.isSingleton()&&0===n.getInstances().length&&n.initialiseSingleton();const i=n.callMethod("listens")[e];n.getInstances().forEach((n=>{if(!r)if("function"==typeof i)try{!1===i.apply(n,s)&&(r=!0)}catch(s){this.error(`Error thrown in "${e}" event by "${t}" plugin.`,s)}else if("string"==typeof i){if(!n[i])throw new Error(`Missing "${i}" method in "${t}" plugin`);try{!1===n[i](...s)&&(r=!0,this.debug(`Global event "${e}" cancelled by "${t}" plugin`))}catch(s){this.error(`Error thrown in "${e}" event by "${t}" plugin.`,s)}}else this.error(`Listen method for "${e}" event in "${t}" plugin is not a function or string.`)}))})),!r&&this.listeners[e]&&this.listeners[e].length>0&&(this.debug(`Found ${this.listeners[e].length} ad-hoc listener(s) for global event "${e}"`),this.listeners[e].forEach((t=>{if(!r)try{!1===t(...s)&&(r=!0,this.debug(`Global event "${e} cancelled by an ad-hoc listener.`))}catch(t){this.error(`Error thrown in "${e}" event by an ad-hoc listener.`,t)}}))),!r}globalPromiseEvent(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n{const n=this.getPlugin(t);if(n.isFunction())return;n.isSingleton()&&0===n.getInstances().length&&n.initialiseSingleton();const i=n.callMethod("listens")[e];n.getInstances().forEach((n=>{if("function"==typeof i)try{const e=i.apply(n,s);if(e instanceof Promise==!1)return;r.push(e)}catch(s){this.error(`Error thrown in "${e}" event by "${t}" plugin.`,s)}else if("string"==typeof i){if(!n[i])throw new Error(`Missing "${i}" method in "${t}" plugin`);try{const e=n[i](...s);if(e instanceof Promise==!1)return;r.push(e)}catch(s){this.error(`Error thrown in "${e}" promise event by "${t}" plugin.`,s)}}else this.error(`Listen method for "${e}" event in "${t}" plugin is not a function or string.`)}))})),this.listeners[e]&&this.listeners[e].length>0&&(this.debug(`Found ${this.listeners[e].length} ad-hoc listener(s) for global promise event "${e}"`),this.listeners[e].forEach((t=>{try{const e=t(...s);if(e instanceof Promise==!1)return;r.push(e)}catch(t){this.error(`Error thrown in "${e}" promise event by an ad-hoc listener.`,t)}}))),0===r.length?Promise.resolve():Promise.all(r)}logMessage(e,t,s){console.groupCollapsed("%c[Snowboard]",`color: ${e}; font-weight: ${t?"bold":"normal"};`,s);for(var n=arguments.length,i=new Array(n>3?n-3:0),r=3;r{e+=1,console.log(`%c${e}:`,"color: rgb(88, 88, 88); font-weight: normal;",t)})),console.groupEnd(),console.groupCollapsed("%cTrace","color: rgb(45, 167, 199); font-weight: bold;"),console.trace(),console.groupEnd()}else console.trace();console.groupEnd()}log(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n1?t-1:0),n=1;n1?t-1:0),n=1;n0&&(this.resetEvents(),this.createTriggerEvents(),this.runEvents(),this.snowboard.globalEvent("triggers.ready",this.element,this.triggers))}destruct(){this.resetEvents(),super.destruct()}parseTriggers(){const{dataset:e}=this.element;this.triggers.clear(),Object.keys(e).forEach((t=>{if(/-[A-Z]/.test(t))throw new Error(`Unable to convert camelCase to dash-style for data attribute: ${t}`);const s=t.replace(/([A-Z])/g,(e=>`-${e.toLowerCase()}`));if("trigger"!==s&&!s.startsWith("trigger-"))return;const n=/([a-z0-9\-.:_]+?)(?:(?:-)(closest-parent|condition|when|action|parent|priority|do))?(?:(?<=(?:action|do)(\.oneway)?)(\.oneway))?$/i.exec(s.replace("trigger-","").toLowerCase());let i=null,r=null;if(-1!==["trigger","condition","action","parent","when","closest"].indexOf(n[1])&&("closest"!==n[1]||"closest"===n[1]&&"parent"===n[2]))i="__original",r="closest"===n[1]?"parent":n[1];else if(void 0===n[2]||-1!==["closest-parent","condition","when","action","parent","priority","do"].indexOf(n[2]))switch([,i]=n,n[2]){case"closest-parent":case"parent":r="parent";break;case"condition":case"when":r="condition";break;case"action":case"do":r="action";break;case"priority":r="priority";break;default:r="trigger"}this.triggers.has(i)||this.triggers.set(i,new Map),this.triggers.get(i).set(r,e[t]),delete e[t]})),this.triggers.forEach(((e,t)=>{const s=this.getSelectableElements(e);e.has("trigger")&&e.has("condition")&&e.has("action")&&0!==s.length&&this.hasValidConditions(e)&&this.hasValidActions(e)?(e.set("elements",s),e.has("priority")||e.set("priority",100)):this.triggers.delete(t)}))}parseCommand(e){let t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(e.startsWith("value")&&e.includes("[")){const t=e.match(/[^[\]]+(?=])/g),s=[];return t.forEach((e=>{if(!e.includes(","))return void s.push(e.replace(/^['"]|['"]$/g,"").trim());const t=e.replace(/('.*?(?e.replace(/,/g,"|||"))).split(",").map((e=>e.replace(/\|\|\|/g,",").replace(/^['"]|['"]$/g,"").trim()));s.push(...t)})),[{name:"value",parameters:s,oneWay:!1}]}if(e.includes("|")&&t){const t=e.replace(/('.*?(?e.replace(/\|/g,"|||"))).split("|").map((e=>e.replace(/\|\|\|/g,"|"))),s=[];return t.forEach((e=>{s.push(...this.parseCommand(e,!1))})),s}if(!e.includes(":"))return e.includes(".oneway")&&(e.startsWith("do")||e.startsWith("action"))?[{name:e.replace(".oneway",""),parameters:[],oneWay:!0}]:[{name:e,parameters:[],oneWay:!1}];const[,s,n]=e.match(/^([a-zA-Z]+):(.*)$/);let i=s,r=!1;if(s.includes(".oneway")&&(s.startsWith("do")||s.startsWith("action"))&&(i=e.replace(".oneway",""),r=!0),!n.includes(","))return[{name:i,parameters:[n.replace(/^['"]|['"]$/g,"").replace(/\\(['"])/,"$1").trim()],oneWay:r}];return[{name:i,parameters:n.replace(/('.*?(?e.replace(/,/g,"|||"))).split(",").map((e=>e.replace(/\|\|\|/g,",").replace(/^['"]|['"]$/g,"").replace(/\\(['"])/,"$1").trim())),oneWay:r}]}getSelectableElements(e){return e.has("parent")?this.element.closest(e.get("parent"))?Array.from(this.element.closest(e.get("parent")).querySelectorAll(e.get("trigger"))):[]:Array.from(document.querySelectorAll(e.get("trigger")))}hasValidConditions(e){return this.parseCommand(e.get("condition")).every((e=>["checked","unchecked","empty","value","oneof","allof","focus","within","notWithin"].includes(e.name.toLowerCase())))}hasValidActions(e){return this.parseCommand(e.get("action")).every((e=>["show","hide","enable","disable","empty","value","valueOf","check","uncheck","class","classOf","attr","attrOf","style","styleOf"].includes(e.name.toLowerCase())))}createTriggerEvents(){this.triggers.forEach((e=>{e.set("conditionCallbacks",[]),e.set("elementEvents",new Map),this.parseCommand(e.get("condition")).forEach((t=>{switch(t.name.toLowerCase()){case"value":case"oneof":e.get("conditionCallbacks").push(this.createValueCondition(e,!1,...t.parameters));break;case"allof":e.get("conditionCallbacks").push(this.createValueCondition(e,!0,...t.parameters));break;case"empty":e.get("conditionCallbacks").push(this.createEmptyCondition(e));break;case"checked":case"unchecked":e.get("conditionCallbacks").push(this.createCheckedCondition(e,"checked"===t.name,...t.parameters));break;case"focus":e.get("conditionCallbacks").push(this.createFocusedCondition(e));break;case"within":case"notwithin":e.get("conditionCallbacks").push(this.createWithinCondition(e,"within"===t.name,...t.parameters))}}))})),this.registerEventListeners()}addEvent(e,t,s){t.get("elementEvents").has(e)||t.get("elementEvents").set(e,new Set),t.get("elementEvents").get(e).add(s)||t.get("elementEvents").get(e).add(s)}registerEventListeners(){const e=new Set;this.triggers.forEach((t=>{t.get("elementEvents").forEach(((s,n)=>{this.events.has(n)||this.events.set(n,new Set),s.forEach((s=>{e.has({element:n,eventName:s})||e.add({element:n,eventName:s});const i={element:n,eventName:s,priority:Number(t.get("priority")),event:()=>{let e=null;this.executeActions(t,t.get("conditionCallbacks").every((t=>{const s=t(e);return!1!==s&&(e=s,!0)})))}};this.events.get(n).add(i)}))}))})),e.forEach((e=>{let{element:t,eventName:s}=e;this.connectors.has(t)||this.connectors.set(t,new Map),this.connectors.get(t).has(s)||(this.connectors.get(t).set(s,(()=>{const e=[];this.events.get(t).forEach((t=>{t.eventName===s&&e.push(t)})),e.sort(((e,t)=>e.priority-t.priority)).forEach((e=>{e.event()}))})),t.addEventListener(s,this.connectors.get(t).get(s)))}))}createValueCondition(e,t){for(var s=arguments.length,n=new Array(s>2?s-2:0),i=2;i{e.matches("input[type=button], input[type=file], input[type=image], input[type=reset], input[type=submit]")||e.matches("input, select, textarea")&&r.add(e)})),r.forEach((t=>{if(t.matches("input[type=checkbox], input[type=radio]"))return this.addEvent(t,e,"click"),void this.addEvent(t,e,"change");t.matches("input[type=hidden]")?this.addEvent(t,e,"change"):this.addEvent(t,e,"input")})),function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;const s=new Map;(e??r).forEach((e=>{e.matches("input[type=checkbox], input[type=radio]")?e.checked&&s.set(e,e.value):s.set(e,e.value)}));return!!(t?n.every((e=>s.values().find((t=>t===e)))):n.some((e=>s.values().find((t=>t===e)))))&&Array.from(s.entries().filter((e=>{let[,t]=e;return n.includes(t)})).map((e=>{let[,t]=e;return t})))}}createEmptyCondition(e){const t=new Set;return e.get("elements").forEach((e=>{e.matches("input[type=button], input[type=image], input[type=reset], input[type=submit]")||e.matches("input, select, textarea")&&t.add(e)})),t.forEach((t=>{if(t.matches("input[type=checkbox], input[type=radio]"))return this.addEvent(t,e,"click"),void this.addEvent(t,e,"change");this.addEvent(t,e,"input")})),function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;const s=new Set,n=e??t;n.forEach((e=>{e.matches("input[type=checkbox], input[type=radio]")?e.checked&&s.add(e):""!==e.value.trim()&&s.add(e)}));return!(0!==s.size)&&Array.from(n.keys().filter((e=>!s.has(e))))}}createCheckedCondition(e,t){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:void 0;const i=new Set;return e.get("elements").forEach((e=>{e.matches("input[type=radio], input[type=checkbox]")&&i.add(e)})),i.forEach((t=>{this.addEvent(t,e,"click")})),function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;const r=new Set,o=e??i;if(o.forEach((e=>{t===e.checked&&r.add(e)})),"all"===s)return r.size===o.size&&Array.from(r);const a=void 0!==s&&Math.floor(s)>0?Math.floor(s):1,l=void 0!==s&&Math.floor(n)>0?Math.floor(n):i.size;return r.size>=a&&r.size<=l&&Array.from(r)}}createFocusedCondition(e){const t=new Set;return e.get("elements").forEach((e=>{t.add(e)})),t.forEach((t=>{this.addEvent(t,e,"focus"),this.addEvent(t,e,"blur")})),function(){const e=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:null)??t,s=Array.from(e).find((e=>document.activeElement===e));return!!s&&[s]}}createWithinCondition(e,t,s){const n=new Set;return e.get("elements").forEach((e=>{n.add(e)})),n.forEach((t=>{this.addEvent(t,e,"click"),this.addEvent(t,e,"change"),this.addEvent(t,e,"focus"),this.addEvent(t,e,"blur")})),function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;const i=new Set,r=e??n;return r.forEach((e=>{let n=!1;document.querySelectorAll(s).forEach((t=>{!0!==n&&t.contains(e)&&(n=!0)})),n===t&&i.add(e)})),i.size===r.length&&Array.from(i)}}runEvents(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0;this.connectors.forEach(((t,s)=>{e&&s!==e||t.forEach((e=>{e()}))}))}resetEvents(){this.connectors.forEach(((e,t)=>{e.forEach(((e,s)=>{t.removeEventListener(s,e)}))})),this.connectors.clear(),this.events.clear()}executeActions(e,t){this.parseCommand(e.get("action")).forEach((s=>{if(!1!==this.snowboard.globalEvent("trigger.action",this.element,e,s,t)){if(!s.oneWay||t)switch(s.name){case"show":case"hide":this.actionShow(e,t,s.parameters[0]?Array.from(this.element.querySelectorAll(s.parameters[0])):[this.element],"show"===s.name?t:!t);break;case"enable":case"disable":this.actionEnable(e,t,s.parameters[0]?Array.from(this.element.querySelectorAll(s.parameters[0])):[this.element],"enable"===s.name?t:!t);break;case"empty":t&&this.actionValue(e,t,s.parameters[0]?Array.from(this.element.querySelectorAll(s.parameters[0])):[this.element],"");break;case"value":case"valueOf":this.actionValue(e,t,"valueOf"===s.name?Array.from(this.element.querySelectorAll(s.parameters[0])):[this.element],...s.parameters.length>0&&"valueOf"===s.name?s.parameters.slice(1):s.parameters);break;case"class":case"classOf":this.actionClass(e,t,"classOf"===s.name?Array.from(this.element.querySelectorAll(s.parameters[0])):[this.element],..."classOf"===s.name?s.parameters.slice(1):s.parameters)}}else this.afterAction(e,this.element,{action:s.name,override:!0,conditionMet:t})}))}actionShow(e,t,s,n){s.forEach((s=>{!n||s.style.display&&"none"!==s.style.display?n||s.style.display&&"none"===s.style.display||(s.style.display&&(s.dataset.originalDisplay=s.style.display),s.style.display="none",this.afterAction(e,s,{action:"show",conditionMet:t,show:n})):(void 0!==s.dataset.originalDisplay?(s.style.display=s.dataset.originalDisplay,delete s.dataset.originalDisplay):s.style.display&&(s.style.display=null),this.afterAction(e,s,{action:"show",conditionMet:t,show:n}))}))}actionEnable(e,t,s,n){s.forEach((s=>{s.classList[n?"remove":"add"]("control-disabled"),void 0!==s.disabled&&(s.disabled=!n),this.afterAction(e,s,{action:"enable",conditionMet:t,enable:n})}))}actionValue(e,t,s,n){let i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:void 0;if(!t&&void 0===i)return;const r=t?n:i;s.forEach((s=>{s.matches("input[type=checkbox], input[type=radio]")?s.checked=s.value===r:s.matches("input, select, textarea")?s.value=r:(s.textContent=r,this.afterAction(e,s,{action:"value",conditionMet:t,value:n,unmetValue:i}))}))}actionClass(e,t,s,n){let i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:void 0;s.forEach((s=>{t?(s.classList.add(n),i&&s.classList.remove(i)):(s.classList.remove(n),i&&s.classList.add(i)),this.afterAction(e,s,{action:"class",conditionMet:t,cssClass:n,unmetCssClass:i})}))}afterAction(e,t,s){this.snowboard.debug("Trigger fired",t,e,s),this.snowboard.globalEvent("trigger.fired",t,e,s)}}if(void 0===window.Snowboard)throw new Error("Snowboard must be loaded in order to use the extra plugins.");(n=window.Snowboard).addPlugin("assetLoader",h.A),n.addPlugin("dataConfig",c.A),n.addPlugin("extrasStyles",l.A),n.addPlugin("transition",r.A),n.addPlugin("flash",i.A),n.addPlugin("attachLoading",o.A),n.addPlugin("stripeLoader",a.A),n.addPlugin("trigger",u)},2:function(e,t,s){var n=s(160),i=s(54);(e=>{const t=new Proxy(new n.A,i.A);e.snowboard=t,e.Snowboard=t,e.SnowBoard=t})(window)},59:function(e,t,s){var n=s(660);function i(e,t){var s=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),s.push.apply(s,n)}return s}function r(e){for(var t=1;t{e&&this.doAjax().then((e=>{if(e.cancelled)return this.cancelled=!0,void this.complete();this.responseData=e,this.processUpdate(e).then((()=>{!1===e.X_WINTER_SUCCESS?this.processError(e):this.processResponse(e)}))}),(e=>{this.responseError=e,this.processError(e)}))})):this.doAjax().then((e=>{if(e.cancelled)return this.cancelled=!0,void this.complete();this.responseData=e,this.processUpdate(e).then((()=>{!1===e.X_WINTER_SUCCESS?this.processError(e):this.processResponse(e)}))}),(e=>{this.responseError=e,this.processError(e)})):this.cancelled=!0}else this.cancelled=!0}dependencies(){return["cookie","jsonParser"]}checkRequest(){if(this.element&&this.element instanceof Element==!1)throw new Error("The element provided must be an Element instance");if(void 0===this.handler)throw new Error("The AJAX handler name is not specified.");if(!this.isHandlerName(this.handler))throw new Error('Invalid AJAX handler name. The correct handler name format is: "onEvent".')}getFetch(){return this.fetchOptions=void 0!==this.options.fetchOptions&&"object"==typeof this.options.fetchOptions?this.options.fetchOptions:{method:"POST",headers:this.headers,body:this.data,redirect:"follow",mode:"same-origin"},this.snowboard.globalEvent("ajaxFetchOptions",this.fetchOptions,this),fetch(this.url,this.fetchOptions)}doClientValidation(){return!0!==this.options.browserValidate||!this.form||!1!==this.form.checkValidity()||(this.form.reportValidity(),!1)}doAjax(){if(!1===this.snowboard.globalEvent("ajaxBeforeSend",this))return Promise.resolve({cancelled:!0});const e=new Promise(((e,t)=>{this.getFetch().then((s=>{s.ok||406===s.status?s.headers.has("Content-Type")&&s.headers.get("Content-Type").includes("/json")?s.json().then((t=>{e(r(r({},t),{},{X_WINTER_SUCCESS:406!==s.status,X_WINTER_RESPONSE_CODE:s.status}))}),(e=>{t(this.renderError(`Unable to parse JSON response: ${e}`))})):s.text().then((t=>{e(t)}),(e=>{t(this.renderError(`Unable to process response: ${e}`))})):s.headers.has("Content-Type")&&s.headers.get("Content-Type").includes("/json")?s.json().then((e=>{e.message&&e.exception?t(this.renderError(e.message,e.exception,e.file,e.line,e.trace)):t(e)}),(e=>{t(this.renderError(`Unable to parse JSON response: ${e}`))})):s.text().then((e=>{t(this.renderError(e))}),(e=>{t(this.renderError(`Unable to process response: ${e}`))}))}),(e=>{t(this.renderError(`Unable to retrieve a response from the server: ${e}`))}))}));if(this.snowboard.globalEvent("ajaxStart",e,this),this.element){const t=new Event("ajaxPromise");t.promise=e,this.element.dispatchEvent(t)}return e}processUpdate(e){return new Promise(((t,s)=>{if("function"==typeof this.options.beforeUpdate&&!1===this.options.beforeUpdate.apply(this,[e]))return void t();const n={};if(Object.entries(e).forEach((e=>{const[t,s]=e;"X_WINTER"!==t.substr(0,8)&&(n[t]=s)})),0===Object.keys(n).length)return void(e.X_WINTER_ASSETS?this.processAssets(e.X_WINTER_ASSETS).then((()=>{t()}),(()=>{s()})):t());this.snowboard.globalPromiseEvent("ajaxBeforeUpdate",e,this).then((async()=>{e.X_WINTER_ASSETS&&await this.processAssets(e.X_WINTER_ASSETS),this.doUpdate(n).then((()=>{window.requestAnimationFrame((()=>t()))}),(()=>{s()}))}),(()=>{t()}))}))}doUpdate(e){return new Promise((t=>{const s=[];Object.entries(e).forEach((e=>{const[t,n]=e;let i=this.options.update&&this.options.update[t]?this.options.update[t]:t,r="replace";"@"===i.substr(0,1)?(r="append",i=i.substr(1)):"^"===i.substr(0,1)?(r="prepend",i=i.substr(1)):"#"!==i.substr(0,1)&&"."!==i.substr(0,1)&&(r="noop");const o=document.querySelectorAll(i);o.length>0&&o.forEach((e=>{switch(r){case"append":e.innerHTML+=n;break;case"prepend":e.innerHTML=n+e.innerHTML;break;case"noop":break;default:e.innerHTML=n}s.push(e),this.snowboard.globalEvent("ajaxUpdate",e,n,this);const t=new Event("ajaxUpdate");t.content=n,e.dispatchEvent(t)}))})),this.snowboard.globalEvent("ajaxUpdateComplete",s,this),t()}))}processResponse(e){if((!this.options.success||"function"!=typeof this.options.success||!1!==this.options.success(this.responseData,this))&&!1!==this.snowboard.globalEvent("ajaxSuccess",this.responseData,this)){if(this.element){const e=new Event("ajaxDone",{cancelable:!0});if(e.responseData=this.responseData,e.request=this,this.element.dispatchEvent(e),e.defaultPrevented)return}this.flash&&e.X_WINTER_FLASH_MESSAGES&&this.processFlashMessages(e.X_WINTER_FLASH_MESSAGES),this.redirect||e.X_WINTER_REDIRECT?this.processRedirect(this.redirect||e.X_WINTER_REDIRECT):this.complete()}}processError(e){if((!this.options.error||"function"!=typeof this.options.error||!1!==this.options.error(this.responseError,this))&&!1!==this.snowboard.globalEvent("ajaxError",this.responseError,this)){if(this.element){const e=new Event("ajaxFail",{cancelable:!0});if(e.responseError=this.responseError,e.request=this,this.element.dispatchEvent(e),e.defaultPrevented)return}if(e instanceof Error)this.processErrorMessage(e.message);else{let t=!1;e.X_WINTER_ERROR_FIELDS&&(t=this.processValidationErrors(e.X_WINTER_ERROR_FIELDS)),e.X_WINTER_ERROR_MESSAGE&&!t&&this.processErrorMessage(e.X_WINTER_ERROR_MESSAGE)}this.complete()}}processRedirect(e){"function"==typeof this.options.handleRedirectResponse&&!1===this.options.handleRedirectResponse.apply(this,[e])||!1!==this.snowboard.globalEvent("ajaxRedirect",e,this)&&(window.addEventListener("popstate",(()=>{if(this.element){const e=document.createEvent("CustomEvent");e.eventName="ajaxRedirected",this.element.dispatchEvent(e)}}),{once:!0}),window.location.assign(e))}processErrorMessage(e){"function"==typeof this.options.handleErrorMessage&&!1===this.options.handleErrorMessage.apply(this,[e])||!1!==this.snowboard.globalEvent("ajaxErrorMessage",e,this)&&window.alert(e)}processFlashMessages(e){"function"==typeof this.options.handleFlashMessages&&!1===this.options.handleFlashMessages.apply(this,[e])||this.snowboard.globalEvent("ajaxFlashMessages",e,this)}processValidationErrors(e){return"function"==typeof this.options.handleValidationErrors&&!1===this.options.handleValidationErrors.apply(this,[this.form,e])||!1===this.snowboard.globalEvent("ajaxValidationErrors",this.form,e,this)}processAssets(e){return this.snowboard.globalPromiseEvent("ajaxLoadAssets",e)}async doConfirm(){if("function"==typeof this.options.handleConfirmMessage)return!1!==this.options.handleConfirmMessage.apply(this,[this.confirm]);if(0===this.snowboard.listensToEvent("ajaxConfirmMessage").length)return window.confirm(this.confirm);const e=this.snowboard.globalPromiseEvent("ajaxConfirmMessage",this.confirm,this);try{if(await e)return!0}catch(e){return!1}return!1}complete(){if(this.options.complete&&"function"==typeof this.options.complete&&this.options.complete(this.responseData,this),this.snowboard.globalEvent("ajaxDone",this.responseData,this),this.element){const e=new Event("ajaxAlways");e.request=this,e.responseData=this.responseData,e.responseError=this.responseError,this.element.dispatchEvent(e)}this.destruct()}get form(){return this.options.form?"string"==typeof this.options.form?document.querySelector(this.options.form):this.options.form:this.element?"FORM"===this.element.tagName?this.element:this.element.closest("form"):null}get context(){return{handler:this.handler,options:this.options}}get headers(){const e={"X-Requested-With":"XMLHttpRequest","X-WINTER-REQUEST-HANDLER":this.handler,"X-WINTER-REQUEST-PARTIALS":this.extractPartials(this.options.update||[])};return this.flash&&(e["X-WINTER-REQUEST-FLASH"]=1),this.xsrfToken&&(e["X-XSRF-TOKEN"]=this.xsrfToken),e}get loading(){return this.options.loading||!1}get url(){return this.options.url||window.location.href}get redirect(){return this.options.redirect&&this.options.redirect.length?this.options.redirect:null}get flash(){return this.options.flash||!1}get files(){return!0===this.options.files&&(void 0!==FormData||(this.snowboard.debug("This browser does not support file uploads"),!1))}get xsrfToken(){return this.snowboard.cookie().get("XSRF-TOKEN")}get data(){const e="object"==typeof this.options.data?this.options.data:{},t=new FormData(this.form||void 0);return Object.keys(e).length>0&&this.createFormData(t,e),t}createFormData(e,t){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";"object"==typeof t?Array.isArray(t)&&""!==s?t.forEach((t=>{this.createFormData(e,t,`${s}[]`)})):Object.entries(t).forEach((t=>{const[n,i]=t;this.createFormData(e,i,""!==s?`${s}[${n}]`:n)})):e.append(s,t)}get confirm(){return this.options.confirm||!1}extractPartials(e){return Object.keys(e).join("&")}renderError(e,t,s,n,i){const r=new Error(e);return r.exception=t||null,r.file=s||null,r.line=n||null,r.trace=i||[],r}isHandlerName(e){return/^(?:\w+:{2})?on[A-Z0-9]/.test(e)}}if(void 0===window.Snowboard)throw new Error("Snowboard must be loaded in order to use the Javascript AJAX request feature.");window.Snowboard.addPlugin("request",a)},557:function(){},740:function(){},48:function(){},27:function(){},730:function(){},909:function(){}},function(e){var t=function(t){return e(e.s=t)};e.O(0,[969,778,321,955,71,261,214],(function(){return t(2),t(59),t(222),t(740),t(48),t(27),t(730),t(909),t(557)}));e.O()}]); \ No newline at end of file diff --git a/modules/system/assets/js/snowboard/build/snowboard.data-attr.js b/modules/system/assets/js/snowboard/build/snowboard.data-attr.js index d27565a181..4ea149d901 100644 --- a/modules/system/assets/js/snowboard/build/snowboard.data-attr.js +++ b/modules/system/assets/js/snowboard/build/snowboard.data-attr.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_wintercms_wn_system_module=self.webpackChunk_wintercms_wn_system_module||[]).push([[14],{660:function(e,t,r){r.d(t,{A:function(){return n}});class n{constructor(e){this.snowboard=e}construct(){}dependencies(){return[]}listens(){return{}}destruct(){this.detach(),delete this.snowboard}destructor(){this.destruct()}}},373:function(e,t,r){r.d(t,{A:function(){return a}});var n=r(660);class a extends n.A{}},364:function(e,t,r){var n=r(373);function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;tthis.changeHandler(e))),window.addEventListener("click",(e=>this.clickHandler(e))),window.addEventListener("keydown",(e=>this.keyDownHandler(e))),window.addEventListener("submit",(e=>this.submitHandler(e)))}disableDefaultFormValidation(){document.querySelectorAll("form[data-request]:not([data-browser-validate])").forEach((e=>{e.setAttribute("novalidate",!0)}))}detachHandlers(){window.removeEventListener("change",(e=>this.changeHandler(e))),window.removeEventListener("click",(e=>this.clickHandler(e))),window.removeEventListener("keydown",(e=>this.keyDownHandler(e))),window.removeEventListener("submit",(e=>this.submitHandler(e)))}changeHandler(e){e.target.matches("select[data-request], input[type=radio][data-request], input[type=checkbox][data-request], input[type=file][data-request]")&&this.processRequestOnElement(e.target)}clickHandler(e){let t=e.target;for(;t&&"HTML"!==t.tagName;){if(t.matches("a[data-request], button[data-request], input[type=button][data-request], input[type=submit][data-request]")){e.preventDefault(),this.processRequestOnElement(t);break}t=t.parentElement}}keyDownHandler(e){if(!e.target.matches("input"))return;-1!==["checkbox","color","date","datetime","datetime-local","email","image","month","number","password","radio","range","search","tel","text","time","url","week"].indexOf(e.target.getAttribute("type"))&&("Enter"===e.key&&e.target.matches("*[data-request]")?(this.processRequestOnElement(e.target),e.preventDefault(),e.stopImmediatePropagation()):e.target.matches("*[data-track-input]")&&this.trackInput(e.target))}submitHandler(e){e.target.matches("form[data-request]")&&(e.preventDefault(),this.processRequestOnElement(e.target))}processRequestOnElement(e){const t=e.dataset,r=String(t.request),n={confirm:"requestConfirm"in t?String(t.requestConfirm):null,redirect:"requestRedirect"in t?String(t.requestRedirect):null,loading:"requestLoading"in t?String(t.requestLoading):null,flash:"requestFlash"in t,files:"requestFiles"in t,browserValidate:"requestBrowserValidate"in t,form:"requestForm"in t?String(t.requestForm):null,url:"requestUrl"in t?String(t.requestUrl):null,update:"requestUpdate"in t?this.parseData(String(t.requestUpdate)):[],data:"requestData"in t?this.parseData(String(t.requestData)):[]};this.snowboard.request(e,r,n)}onAjaxSetup(e){if(!e.element)return;const t=e.element.getAttribute("name"),r=s(s({},this.getParentRequestData(e.element)),e.options.data);e.element&&e.element.matches("input, textarea, select, button")&&!e.form&&t&&!e.options.data[t]&&(r[t]=e.element.value),e.options.data=r}getParentRequestData(e){const t=[];let r={},n=e;for(;n.parentElement&&"HTML"!==n.parentElement.tagName;)t.push(n.parentElement),n=n.parentElement;return t.reverse(),t.forEach((e=>{const t=e.dataset;"requestData"in t&&(r=s(s({},r),this.parseData(t.requestData)))})),r}parseData(e){let t;if(void 0===e&&(t=""),"object"==typeof t)return t;try{return this.snowboard.jsonparser().parse(`{${e}}`)}catch(e){throw new Error(`Error parsing the data attribute on element: ${e.message}`)}}trackInput(e){const{lastValue:t}=e.dataset,r=e.dataset.trackInput||300;void 0!==t&&t===e.value||(this.resetTrackInputTimer(e),e.dataset.inputTimer=window.setTimeout((()=>{if(e.dataset.request)return void this.processRequestOnElement(e);let t=e;for(;t.parentElement&&"HTML"!==t.parentElement.tagName;)if(t=t.parentElement,"FORM"===t.tagName&&t.dataset.request){this.processRequestOnElement(t);break}}),r))}resetTrackInputTimer(e){e.dataset.inputTimer&&(window.clearTimeout(e.dataset.inputTimer),e.dataset.inputTimer=null)}}if(void 0===window.Snowboard)throw new Error("Snowboard must be loaded in order to use the HTML data attribute AJAX request feature.");window.Snowboard.addPlugin("attributeRequest",o)}},function(e){var t;t=364,e(e.s=t)}]); \ No newline at end of file +"use strict";(self.webpackChunk_wintercms_wn_system_module=self.webpackChunk_wintercms_wn_system_module||[]).push([[14],{660:function(e,t,r){r.d(t,{A:function(){return n}});class n{constructor(e){this.snowboard=e}construct(){}dependencies(){return[]}listens(){return{}}destruct(){this.detach(),delete this.snowboard}destructor(){this.destruct()}}},373:function(e,t,r){r.d(t,{A:function(){return a}});var n=r(660);class a extends n.A{}},364:function(e,t,r){var n=r(373);function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;tthis.changeHandler(e))),window.addEventListener("click",(e=>this.clickHandler(e))),window.addEventListener("keydown",(e=>this.keyDownHandler(e))),window.addEventListener("submit",(e=>this.submitHandler(e)))}disableDefaultFormValidation(){document.querySelectorAll("form[data-request]:not([data-browser-validate])").forEach((e=>{e.setAttribute("novalidate",!0)}))}detachHandlers(){window.removeEventListener("change",(e=>this.changeHandler(e))),window.removeEventListener("click",(e=>this.clickHandler(e))),window.removeEventListener("keydown",(e=>this.keyDownHandler(e))),window.removeEventListener("submit",(e=>this.submitHandler(e)))}changeHandler(e){e.target.matches("select[data-request], input[type=radio][data-request], input[type=checkbox][data-request], input[type=file][data-request]")&&this.processRequestOnElement(e.target)}clickHandler(e){let t=e.target;for(;t&&"HTML"!==t.tagName;){if(t.matches("a[data-request], button[data-request], input[type=button][data-request], input[type=submit][data-request]")){e.preventDefault(),this.processRequestOnElement(t);break}t=t.parentElement}}keyDownHandler(e){if(!e.target.matches("input"))return;-1!==["checkbox","color","date","datetime","datetime-local","email","image","month","number","password","radio","range","search","tel","text","time","url","week"].indexOf(e.target.getAttribute("type"))&&("Enter"===e.key&&e.target.matches("*[data-request]")?(this.processRequestOnElement(e.target),e.preventDefault(),e.stopImmediatePropagation()):e.target.matches("*[data-track-input]")&&this.trackInput(e.target))}submitHandler(e){e.target.matches("form[data-request]")&&(e.preventDefault(),this.processRequestOnElement(e.target))}processRequestOnElement(e){const t=e.dataset,r=String(t.request),n={confirm:"requestConfirm"in t?String(t.requestConfirm):null,redirect:"requestRedirect"in t?String(t.requestRedirect):null,loading:"requestLoading"in t?String(t.requestLoading):null,stripe:!("requestStripe"in t)||"true"===t.requestStripe,flash:"requestFlash"in t,files:"requestFiles"in t,browserValidate:"requestBrowserValidate"in t,form:"requestForm"in t?String(t.requestForm):null,url:"requestUrl"in t?String(t.requestUrl):null,update:"requestUpdate"in t?this.parseData(String(t.requestUpdate)):[],data:"requestData"in t?this.parseData(String(t.requestData)):[]};this.snowboard.request(e,r,n)}onAjaxSetup(e){if(!e.element)return;const t=e.element.getAttribute("name"),r=s(s({},this.getParentRequestData(e.element)),e.options.data);e.element&&e.element.matches("input, textarea, select, button")&&!e.form&&t&&!e.options.data[t]&&(r[t]=e.element.value),e.options.data=r}getParentRequestData(e){const t=[];let r={},n=e;for(;n.parentElement&&"HTML"!==n.parentElement.tagName;)t.push(n.parentElement),n=n.parentElement;return t.reverse(),t.forEach((e=>{const t=e.dataset;"requestData"in t&&(r=s(s({},r),this.parseData(t.requestData)))})),r}parseData(e){let t;if(void 0===e&&(t=""),"object"==typeof t)return t;try{return this.snowboard.jsonparser().parse(`{${e}}`)}catch(e){throw new Error(`Error parsing the data attribute on element: ${e.message}`)}}trackInput(e){const{lastValue:t}=e.dataset,r=e.dataset.trackInput||300;void 0!==t&&t===e.value||(this.resetTrackInputTimer(e),e.dataset.inputTimer=window.setTimeout((()=>{if(e.dataset.request)return void this.processRequestOnElement(e);let t=e;for(;t.parentElement&&"HTML"!==t.parentElement.tagName;)if(t=t.parentElement,"FORM"===t.tagName&&t.dataset.request){this.processRequestOnElement(t);break}}),r))}resetTrackInputTimer(e){e.dataset.inputTimer&&(window.clearTimeout(e.dataset.inputTimer),e.dataset.inputTimer=null)}}if(void 0===window.Snowboard)throw new Error("Snowboard must be loaded in order to use the HTML data attribute AJAX request feature.");window.Snowboard.addPlugin("attributeRequest",u)}},function(e){var t;t=364,e(e.s=t)}]); \ No newline at end of file diff --git a/modules/system/assets/js/snowboard/extras/Trigger.js b/modules/system/assets/js/snowboard/extras/Trigger.js new file mode 100644 index 0000000000..abbc8e04b8 --- /dev/null +++ b/modules/system/assets/js/snowboard/extras/Trigger.js @@ -0,0 +1,1085 @@ +import PluginBase from '../abstracts/PluginBase'; + +/** + * @typedef {Object} TriggerEntity + * @property {string} trigger The selector for the trigger target element(s). + * @property {string} condition The condition that must be met for the trigger to fire. + * @property {string} action The action to perform when the trigger fires. + * @property {string|undefined} parent The parent element with which to limit the trigger scope. + * @property {string|number} priority The priority of the trigger event. + * @property {HTMLElement[]} elements The target elements that this trigger applies to. + * @property {boolean} reverse If this is a reverse trigger. The trigger element(s) become the targets and the condition is applied to the target elements. + * @property {Function[]} conditionCallbacks The condition callbacks for this trigger. + * @property {Map>} elementEvents The events registered on the target elements. + */ +/** + * @typedef {Object} TriggerElement + * @property {HTMLElement} element The target element. + * @property {string} eventName The trigger event name. + * @property {int} priority The trigger event priority. + * @property {Function} event The trigger event function. + */ + +/** + * Trigger handler for HTML elements. + * + * This is a re-imagining of the Input.Trigger functionality in the original Winter CMS framework, + * initialised through the `data-trigger` attributes. + * + * In addition to remaining backwards-compatible with the original Input.Trigger functionality, this + * handler adds additional conditions and configuration for more flexible trigger usage. + * + * @see https://wintercms.com/docs/v1.2/ui/script/input-trigger + * + * @copyright 2024 Winter. + * @author Ben Thomson + */ +export default class Trigger extends PluginBase { + /** + * Constructor. + * + * @param {HTMLElement} element + */ + construct(element) { + /** + * The element this instance is attached to. + */ + this.element = element; + + /** + * @type {Map} The triggers for this element. + */ + this.triggers = new Map(); + + /** + * @type {Map>} A map of elements that trigger events. + */ + this.events = new Map(); + + /** + * @type {Map>} A map of elements and their event connectors. + */ + this.connectors = new Map(); + + this.parseTriggers(); + + if (this.triggers.size > 0) { + this.resetEvents(); + this.createTriggerEvents(); + this.runEvents(); + + this.snowboard.globalEvent('triggers.ready', this.element, this.triggers); + } + } + + /** + * Destructor. + */ + destruct() { + this.resetEvents(); + super.destruct(); + } + + /** + * Parses the element's data attributes and determines applicable triggers. + * + * Trigger data attributes must be in the format `data-trigger-[name]-[parameter]` for multiple + * triggers, or `data-trigger-[parameter]` for single triggers. + * + * The main parameter defines the element to watch for the trigger. + * + * Supported parameters are: + * - `condition` or `where`: The condition that must be met for the trigger to fire. + * - `action` or `do`: The action to perform when the trigger fires. + * - `closest-parent` or `parent`: The parent element with which to limit the trigger scope. + * - `priority`: The priority in which to consider the trigger. + * + * Internally, the trigger map uses the `trigger` parameter to store the trigger selector. + */ + parseTriggers() { + const { dataset } = this.element; + this.triggers.clear(); + + Object.keys(dataset).forEach((key) => { + if (/-[A-Z]/.test(key)) { + throw new Error(`Unable to convert camelCase to dash-style for data attribute: ${key}`); + } + + const dashStyle = key.replace(/([A-Z])/g, (match) => `-${match.toLowerCase()}`); + + if (dashStyle !== 'trigger' && !dashStyle.startsWith('trigger-')) { + return; + } + + const triggerParts = /([a-z0-9\-.:_]+?)(?:(?:-)(closest-parent|condition|when|action|parent|priority|do))?(?:(?<=(?:action|do)(\.oneway)?)(\.oneway))?$/i.exec( + dashStyle.replace('trigger-', '').toLowerCase(), + ); + + let triggerName = null; + let triggerType = null; + + if ( + ['trigger', 'condition', 'action', 'parent', 'when', 'closest', 'do', 'action', 'reverse'].indexOf(triggerParts[1]) !== -1 + && (triggerParts[1] !== 'closest' || (triggerParts[1] === 'closest' && triggerParts[2] === 'parent')) + ) { + // Support original trigger format + triggerName = '__original'; + triggerType = (triggerParts[1] === 'closest') ? 'parent' : triggerParts[1]; + } else if ( + triggerParts[2] === undefined + || ['closest-parent', 'condition', 'when', 'action', 'parent', 'priority', 'do'].indexOf(triggerParts[2]) !== -1 + ) { + // Parse multi-trigger format + [, triggerName] = triggerParts; + switch (triggerParts[2]) { + case 'closest-parent': + case 'parent': + triggerType = 'parent'; + break; + case 'condition': + case 'when': + triggerType = 'condition'; + break; + case 'action': + case 'do': + triggerType = 'action'; + break; + case 'priority': + triggerType = 'priority'; + break; + case 'reverse': + triggerType = 'reverse'; + break; + default: + triggerType = 'trigger'; + break; + } + } + + if (!this.triggers.has(triggerName)) { + this.triggers.set(triggerName, new Map()); + } + + if (triggerType === 'reverse') { + this.triggers.get(triggerName).set('reverse', true); + } else { + this.triggers.get(triggerName).set(triggerType, dataset[key]); + } + + // Remove trigger data attribute after parsing + delete dataset[key]; + }); + + // Validate triggers, and remove those that do not have at least a trigger selector, a + // condition and an action, or are using invalid conditions or actions + this.triggers.forEach((trigger, name) => { + const elements = this.getSelectableElements(trigger); + + if ( + !trigger.has('trigger') + || !trigger.has('condition') + || !trigger.has('action') + || elements.length === 0 + || !this.hasValidConditions(trigger) + || !this.hasValidActions(trigger) + ) { + this.triggers.delete(name); + } else { + trigger.set('elements', elements); + if (!trigger.has('priority')) { + trigger.set('priority', 100); + } + } + }); + } + + /** + * Parses a command given as either a condition or an action. + * + * Commands are formatted as: name:parameter1,parameter2,parameter3, although we also support + * the old format of value[parameter1,parameter2,parameter3] for the `value` command only. + * + * If a parameter requires a comma within, the parameter should be wrapped in quotes. + * + * Multiple commands can be separated by a pipe character `|`. + * + * @param {string} command + * @param {string} allowMultiple + * @returns {{name: string, parameters: string[], oneWay: boolean}[]} + */ + parseCommand(command, allowMultiple = true) { + // Support old-format value command (value[foo,bar]) + if (command.startsWith('value') && command.includes('[')) { + const match = command.match(/[^[\]]+(?=])/g); + const values = []; + + // Split values with commas + match.forEach((value) => { + if (!value.includes(',')) { + values.push(value.replace(/^['"]|['"]$/g, '').trim()); + return; + } + + const splitValues = value.replace(/('.*?(? quoted.replace(/,/g, '|||')) + .split(',') + .map((splitValue) => splitValue.replace(/\|\|\|/g, ',').replace(/^['"]|['"]$/g, '').trim()); + + values.push(...splitValues); + }); + + return [{ + name: 'value', + parameters: values, + oneWay: false, + }]; + } + + // Handle multiple commands + if (command.includes('|') && allowMultiple) { + const splitCommands = command.replace(/('.*?(? quoted.replace(/\|/g, '|||')) + .split('|') + .map((splitValue) => splitValue.replace(/\|\|\|/g, '|')); + + const commands = []; + splitCommands.forEach((splitCommand) => { + commands.push(...this.parseCommand(splitCommand, false)); + }); + + return commands; + } + + if (!command.includes(':')) { + if ( + command.includes('.oneway') + && (command.startsWith('do') || command.startsWith('action')) + ) { + return [{ + name: command.replace('.oneway', ''), + parameters: [], + oneWay: true, + }]; + } + + return [{ + name: command, + parameters: [], + oneWay: false, + }]; + } + + const [, name, parameters] = command.match(/^([a-zA-Z]+):(.*)$/); + let finalName = name; + let oneWay = false; + + if ( + name.includes('.oneway') + && (name.startsWith('do') || name.startsWith('action')) + ) { + finalName = command.replace('.oneway', ''); + oneWay = true; + } + + if (!parameters.includes(',')) { + return [{ + name: finalName, + parameters: [parameters.replace(/^['"]|['"]$/g, '').replace(/\\(['"])/, '$1').trim()], + oneWay, + }]; + } + + const splitValues = parameters.replace(/('.*?(? quoted.replace(/,/g, '|||')) + .split(',') + .map((splitValue) => splitValue.replace(/\|\|\|/g, ',').replace(/^['"]|['"]$/g, '').replace(/\\(['"])/, '$1').trim()); + + return [{ + name: finalName, + parameters: splitValues, + oneWay, + }]; + } + + /** + * Checks if any elements are accessible by the provided trigger. + * + * @param {Map} trigger + * @returns {HTMLElement[]} + */ + getSelectableElements(trigger) { + if (trigger.has('parent')) { + if (!this.element.closest(trigger.get('parent'))) { + return []; + } + return Array.from(this.element.closest(trigger.get('parent')).querySelectorAll(trigger.get('trigger'))); + } + + return Array.from(document.querySelectorAll(trigger.get('trigger'))); + } + + /** + * Determines if the provided trigger condition(s) are valid. + * + * @param {TriggerEntity} trigger + * @returns {boolean} + */ + hasValidConditions(trigger) { + return this.parseCommand(trigger.get('condition')).every((condition) => [ + 'click', + 'checked', + 'unchecked', + 'empty', + 'value', + 'oneof', + 'allof', + 'focus', + 'within', + 'notWithin', + ].includes(condition.name.toLowerCase())); + } + + /** + * Determines if the provided trigger action(s) are valid. + * + * @param {TriggerEntity} trigger + * @returns {boolean} + */ + hasValidActions(trigger) { + return this.parseCommand(trigger.get('action')).every((action) => [ + 'show', + 'hide', + 'enable', + 'disable', + 'empty', + 'value', + 'valueOf', + 'check', + 'uncheck', + 'class', + 'classOf', + 'attr', + 'attrOf', + 'style', + 'styleOf', + ].includes(action.name.toLowerCase())); + } + + /** + * Create trigger events on trigger and target elements. + */ + createTriggerEvents() { + this.triggers.forEach((trigger) => { + // Collect conditions and check them as a group. + trigger.set('conditionCallbacks', []); + trigger.set('elementEvents', new Map()); + + this.parseCommand(trigger.get('condition')).forEach((condition) => { + switch (condition.name.toLowerCase()) { + case 'value': + case 'oneof': + trigger.get('conditionCallbacks').push( + this.createValueCondition(trigger, false, ...condition.parameters), + ); + break; + case 'allof': + trigger.get('conditionCallbacks').push( + this.createValueCondition(trigger, true, ...condition.parameters), + ); + break; + case 'empty': + trigger.get('conditionCallbacks').push( + this.createEmptyCondition(trigger), + ); + break; + case 'checked': + case 'unchecked': + trigger.get('conditionCallbacks').push( + this.createCheckedCondition(trigger, (condition.name === 'checked'), ...condition.parameters), + ); + break; + case 'focus': + trigger.get('conditionCallbacks').push( + this.createFocusedCondition(trigger), + ); + break; + case 'within': + case 'notwithin': + trigger.get('conditionCallbacks').push( + this.createWithinCondition(trigger, (condition.name === 'within'), ...condition.parameters), + ); + break; + default: + } + }); + }); + + this.registerEventListeners(); + } + + /** + * Adds an event to an element. + * + * This registers the event in the `elementEvents` map for later usage and removal. + * + * @param {HTMLElement} element + * @param {TriggerEntity} trigger + * @param {string} eventName + */ + addEvent(element, trigger, eventName) { + if (!trigger.get('elementEvents').has(element)) { + trigger.get('elementEvents').set(element, new Set()); + } + if (!trigger.get('elementEvents').get(element).add(eventName)) { + trigger.get('elementEvents').get(element).add(eventName); + } + } + + /** + * Registers DOM event listeners for targeted elements of all triggers. + * + * Adds a connector to the element for the events, so that we may enable prioritisation and + * control over the firing of the events, and then registers DOM event listeners for the + * elements. + */ + registerEventListeners() { + const connectors = new Set(); + + this.triggers.forEach((trigger) => { + trigger.get('elementEvents').forEach((events, element) => { + if (!this.events.has(element)) { + this.events.set(element, new Set()); + } + + events.forEach((eventName) => { + if (!connectors.has({ element, eventName })) { + connectors.add({ element, eventName }); + } + + const event = { + element, + eventName, + priority: Number(trigger.get('priority')), + event: () => { + let chainedElements = null; + + this.executeActions( + trigger, + trigger.get('conditionCallbacks').every((condition) => { + const met = condition(chainedElements); + + if (met === false) { + return false; + } + + chainedElements = met; + return true; + }), + ); + }, + }; + + this.events.get(element).add(event); + }); + }); + }); + + connectors.forEach(({ element, eventName }) => { + if (!this.connectors.has(element)) { + this.connectors.set(element, new Map()); + } + + if (!this.connectors.get(element).has(eventName)) { + this.connectors.get(element).set(eventName, () => { + const events = []; + + this.events.get(element).forEach((elementEvent) => { + if (elementEvent.eventName === eventName) { + events.push(elementEvent); + } + }); + + events + .sort((a, b) => a.priority - b.priority) + .forEach((elementEvent) => { + elementEvent.event(); + }); + }); + + element.addEventListener(eventName, this.connectors.get(element).get(eventName)); + } + }); + } + + /** + * Creates a trigger that fires when the value of the target element(s) matches one of the + * provided values. + * + * @param {TriggerEntity} trigger + * @param {...string} values + */ + createValueCondition(trigger, all, ...values) { + const supportedElements = new Set(); + + trigger.get('elements').forEach((element) => { + if (element.matches('input[type=button], input[type=file], input[type=image], input[type=reset], input[type=submit]')) { + // Buttons and file inputs are unsupported + return; + } + + if (element.matches('input, select, textarea')) { + supportedElements.add(element); + } + }); + + supportedElements.forEach((element) => { + if (element.matches('input[type=checkbox], input[type=radio]')) { + this.addEvent(element, trigger, 'click'); + this.addEvent(element, trigger, 'change'); + return; + } + + if (element.matches('input[type=hidden]')) { + this.addEvent(element, trigger, 'change'); + return; + } + + this.addEvent(element, trigger, 'input'); + }); + + return (chainedElements = null) => { + const elementValues = new Map(); + const testElements = chainedElements ?? supportedElements; + + testElements.forEach((element) => { + if (element.matches('input[type=checkbox], input[type=radio]')) { + if (element.checked) { + elementValues.set(element, element.value); + } + return; + } + + elementValues.set(element, element.value); + }); + + // Check if condition is met + const met = (all) + ? values.every((value) => elementValues.values().find((elementValue) => elementValue === value)) + : values.some((value) => elementValues.values().find((elementValue) => elementValue === value)); + + if (!met) { + return false; + } + + // Return only elements who met the condition + return Array.from(elementValues.entries().filter(([, value]) => values.includes(value)).map(([, element]) => element)); + }; + } + + /** + * Creates a trigger that fires when there is no value within the target element(s). + * + * @param {TriggerEntity} trigger + */ + createEmptyCondition(trigger) { + const supportedElements = new Set(); + + trigger.get('elements').forEach((element) => { + if (element.matches('input[type=button], input[type=image], input[type=reset], input[type=submit]')) { + // Buttons and file inputs are unsupported + return; + } + + if (element.matches('input, select, textarea')) { + supportedElements.add(element); + } + }); + + supportedElements.forEach((element) => { + if (element.matches('input[type=checkbox], input[type=radio]')) { + this.addEvent(element, trigger, 'click'); + this.addEvent(element, trigger, 'change'); + return; + } + + this.addEvent(element, trigger, 'input'); + }); + + return (chainedElements = null) => { + const elementValues = new Set(); + const testElements = chainedElements ?? supportedElements; + + testElements.forEach((element) => { + if (element.matches('input[type=checkbox], input[type=radio]')) { + if (element.checked) { + elementValues.add(element); + } + return; + } + + if (element.value.trim() !== '') { + elementValues.add(element); + } + }); + + const met = elementValues.size === 0; + + if (!met) { + return false; + } + + return Array.from(testElements.keys().filter((element) => !elementValues.has(element))); + }; + } + + /** + * Creates a trigger that fires when a target element(s) is checked/unchecked. + * + * @param {TriggerEntity} trigger + * @param {boolean} checked If the element should be checked or unchecked. + * @param {string|number|undefined} atLeast The minimum number of elements that must be checked. + * Defaults to 1 if undefined. If specified as `all`, all elements must be checked. + */ + createCheckedCondition(trigger, checked, atLeast = undefined, atMost = undefined) { + const supportedElements = new Set(); + + trigger.get('elements').forEach((element) => { + // Only supports checkboxes and radio buttons + if (element.matches('input[type=radio], input[type=checkbox]')) { + supportedElements.add(element); + } + }); + + supportedElements.forEach((element) => { + this.addEvent(element, trigger, 'click'); + }); + + return (chainedElements = null) => { + const elementValues = new Set(); + const testElements = chainedElements ?? supportedElements; + + testElements.forEach((element) => { + if (checked === element.checked) { + elementValues.add(element); + } + }); + + if (atLeast === 'all') { + if (elementValues.size === testElements.size) { + return Array.from(elementValues); + } + + return false; + } + + const atLeastCount = (atLeast !== undefined && Math.floor(atLeast) > 0) + ? Math.floor(atLeast) + : 1; + const atMostCount = (atLeast !== undefined && Math.floor(atMost) > 0) + ? Math.floor(atMost) + : supportedElements.size; + + if (elementValues.size >= atLeastCount && elementValues.size <= atMostCount) { + return Array.from(elementValues); + } + + return false; + }; + } + + /** + * Creates a trigger that fires when a target element(s) is focused. + * + * @param {TriggerEntity} trigger + */ + createFocusedCondition(trigger) { + const supportedElements = new Set(); + + trigger.get('elements').forEach((element) => { + // All elements are supported (technically) + supportedElements.add(element); + }); + + supportedElements.forEach((element) => { + this.addEvent(element, trigger, 'focus'); + this.addEvent(element, trigger, 'blur'); + }); + + return (chainedElements = null) => { + const testElements = chainedElements ?? supportedElements; + + const focusedElement = Array.from(testElements).find((element) => document.activeElement === element); + + if (focusedElement) { + return [focusedElement]; + } + + return false; + }; + } + + /** + * Creates a trigger that fires when all supported elements are within a specific element(s). + * + * @param {TriggerEntity} trigger + * @param {boolean} isWithin If the elements must be within the selector. + * @param {string} selector The selector to check if the elements are within. + */ + createWithinCondition(trigger, isWithin, selector) { + const supportedElements = new Set(); + + trigger.get('elements').forEach((element) => { + // All elements are supported (technically) + supportedElements.add(element); + }); + + supportedElements.forEach((element) => { + this.addEvent(element, trigger, 'click'); + this.addEvent(element, trigger, 'change'); + this.addEvent(element, trigger, 'focus'); + this.addEvent(element, trigger, 'blur'); + }); + + return (chainedElements = null) => { + const matchedElements = new Set(); + const testElements = chainedElements ?? supportedElements; + + testElements.forEach((element) => { + let within = false; + + document.querySelectorAll(selector).forEach((parent) => { + if (within === true) { + return; + } + if (parent.contains(element)) { + within = true; + } + }); + + if (within === isWithin) { + matchedElements.add(element); + } + }); + + if (matchedElements.size !== testElements.length) { + return false; + } + + return Array.from(matchedElements); + }; + } + + /** + * Manually runs all registered triggers, optionally for a specific element. + * + * This can be used to update the state of the triggers. + */ + runEvents(forElement = undefined) { + this.connectors.forEach((elementConnectors, element) => { + if (forElement && element !== forElement) { + return; + } + + elementConnectors.forEach((connector) => { + connector(); + }); + }); + } + + /** + * Clears all registered events. + * + * This will disable all triggers and their event listeners on the target elements. + */ + resetEvents() { + this.connectors.forEach((elementConnectors, element) => { + elementConnectors.forEach((connector, event) => { + element.removeEventListener(event, connector); + }); + }); + + this.connectors.clear(); + this.events.clear(); + } + + /** + * Executes actions based on the trigger condition. + * + * Actions should be binary, and show one state when the condition is met, and another when it + * is not. The second parameter is used to determine if the conditions of the trigger have been + * met. If a trigger has multiple conditions, ALL conditions must be met. + * + * @param {TriggerEntity} trigger + * @param {boolean} conditionMet + */ + executeActions(trigger, conditionMet) { + this.parseCommand(trigger.get('action')).forEach((action) => { + // Allow plugins to override action(s) and prevent the default functionality from firing. + if (this.snowboard.globalEvent('trigger.action', this.element, trigger, action, conditionMet) === false) { + this.afterAction(trigger, this.element, { + action: action.name, + override: true, + conditionMet, + }); + return; + } + + // A one-way action won't occur if the condition is not met + if (action.oneWay && !conditionMet) { + return; + } + + switch (action.name) { + case 'show': + case 'hide': + this.actionShow( + trigger, + conditionMet, + (action.parameters[0]) + ? Array.from(this.element.querySelectorAll(action.parameters[0])) + : [this.element], + (action.name === 'show') ? conditionMet : !conditionMet, + ); + break; + case 'enable': + case 'disable': + this.actionEnable( + trigger, + conditionMet, + (action.parameters[0]) + ? Array.from(this.element.querySelectorAll(action.parameters[0])) + : [this.element], + (action.name === 'enable') ? conditionMet : !conditionMet, + ); + break; + case 'empty': + if (conditionMet) { + this.actionValue( + trigger, + conditionMet, + (action.parameters[0]) + ? Array.from(this.element.querySelectorAll(action.parameters[0])) + : [this.element], + '', + ); + } + break; + case 'value': + case 'valueOf': + this.actionValue( + trigger, + conditionMet, + (action.name === 'valueOf') + ? Array.from(this.element.querySelectorAll(action.parameters[0])) + : [this.element], + ...(action.parameters.length > 0 && action.name === 'valueOf') + ? action.parameters.slice(1) + : action.parameters, + ); + break; + case 'class': + case 'classOf': + this.actionClass( + trigger, + conditionMet, + (action.name === 'classOf') + ? Array.from(this.element.querySelectorAll(action.parameters[0])) + : [this.element], + ...(action.name === 'classOf') + ? action.parameters.slice(1) + : action.parameters, + ); + break; + case 'attr': + case 'attrOf': + this.actionAttribute( + trigger, + conditionMet, + (action.name === 'classOf') + ? Array.from(this.element.querySelectorAll(action.parameters[0])) + : [this.element], + ...(action.name === 'classOf') + ? action.parameters.slice(1) + : action.parameters, + ); + break; + default: + } + }); + } + + /** + * Shows or hides a trigger element. + * + * This action will toggle the `hide` class on the element, and set the `display` style to + * `none` when hidden, and the original display value when shown. + * + * @param {TriggerEntity} trigger + * @param {boolean} conditionMet + * @param {HTMLElement[]} elements + * @param {boolean} show + */ + actionShow(trigger, conditionMet, elements, show) { + elements.forEach((element) => { + if (show && (!element.style.display || element.style.display === 'none')) { + if (element.dataset.originalDisplay !== undefined) { + element.style.display = element.dataset.originalDisplay; + delete element.dataset.originalDisplay; + } else if (element.style.display) { + element.style.display = null; + } + + this.afterAction(trigger, element, { + action: 'show', + conditionMet, + show, + }); + } else if (!show && (!element.style.display || element.style.display !== 'none')) { + if (element.style.display) { + element.dataset.originalDisplay = element.style.display; + } + element.style.display = 'none'; + + this.afterAction(trigger, element, { + action: 'show', + conditionMet, + show, + }); + } + }); + } + + /** + * Enables or disables a trigger element. + * + * This action will toggle the `control-disabled` class on the element, and set the `disabled` + * property to `true` when disabled, and `false` when enabled. + * + * @param {TriggerEntity} trigger + * @param {boolean} conditionMet + * @param {HTMLElement[]} elements + * @param {boolean} enable + */ + actionEnable(trigger, conditionMet, elements, enable) { + elements.forEach((element) => { + element.classList[(enable) ? 'remove' : 'add']('control-disabled'); + + if (element.disabled !== undefined) { + element.disabled = !enable; + } + + this.afterAction(trigger, element, { + action: 'enable', + conditionMet, + enable, + }); + }); + } + + /** + * Sets the value of either the trigger element or a child element(s) within. + * + * This is a one-way action if the unmet value is not defined. + */ + actionValue(trigger, conditionMet, elements, value, unmetValue = undefined) { + if (!conditionMet && unmetValue === undefined) { + return; + } + + const newValue = (conditionMet) ? value : unmetValue; + + elements.forEach((element) => { + if (element.matches('input[type=checkbox], input[type=radio]')) { + element.checked = (element.value === newValue); + return; + } + + if (element.matches('input, select, textarea')) { + element.value = newValue; + return; + } + + element.textContent = newValue; + + this.afterAction(trigger, element, { + action: 'value', + conditionMet, + value, + unmetValue, + }); + }); + } + + /** + * Adds or removes the class from the trigger element or a child element(s) within. + * + * This will simply remove the class if the unmet class is not defined. Otherwise, the classes + * will be toggled. + */ + actionClass(trigger, conditionMet, elements, cssClass, unmetCssClass = undefined) { + elements.forEach((element) => { + if (conditionMet) { + element.classList.add(cssClass); + if (unmetCssClass) { + element.classList.remove(unmetCssClass); + } + } else { + element.classList.remove(cssClass); + if (unmetCssClass) { + element.classList.add(unmetCssClass); + } + } + + this.afterAction(trigger, element, { + action: 'class', + conditionMet, + cssClass, + unmetCssClass, + }); + }); + } + + /** + * Sets the attribute of a trigger element or a child element(s) within. + * + * If the unmet attribute value is not defined, the original attribute value will be used, or + * in the case where the attribute did not exist, the attribute will be removed. + */ + actionAttribute(trigger, conditionMet, elements, attributeName, attributeValue, unmetAttributeValue = undefined) { + elements.forEach((element) => { + if (element.dataset[`original-${attributeName}`] === undefined) { + element.dataset[`original-${attributeName}`] = element.getAttribute(attributeName) ?? ''; + } + + if (conditionMet) { + element.setAttribute(attributeName, attributeValue); + } else if (unmetAttributeValue !== undefined) { + element.setAttribute(attributeName, unmetAttributeValue); + } else if (element.dataset[`original-${attributeName}`] !== '') { + element.setAttribute(attributeName, element.dataset[`original-${attributeName}`]); + } else { + element.removeAttribute(attributeName); + } + + this.afterAction(trigger, element, { + action: 'class', + conditionMet, + attributeName, + attributeValue, + unmetAttributeValue, + }); + }); + } + + /** + * Fires off an event when a trigger action has been executed. + * + * The element affected, the trigger and details about the action are passed through to the + * event. + * + * @param {TriggerEntity} trigger + * @param {HTMLElement} element + * @param {Object} action + */ + afterAction(trigger, element, action) { + this.snowboard.debug('Trigger fired', element, trigger, action); + this.snowboard.globalEvent('trigger.fired', element, trigger, action); + } +} diff --git a/modules/system/assets/js/snowboard/snowboard.backend.extras.js b/modules/system/assets/js/snowboard/snowboard.backend.extras.js index 6d4119137c..882df3a0d9 100644 --- a/modules/system/assets/js/snowboard/snowboard.backend.extras.js +++ b/modules/system/assets/js/snowboard/snowboard.backend.extras.js @@ -5,6 +5,7 @@ import StripeLoader from './extras/StripeLoader'; import StylesheetLoader from './extras/StylesheetLoader'; import AssetLoader from './extras/AssetLoader'; import DataConfig from './extras/DataConfig'; +import Trigger from './extras/Trigger'; if (window.Snowboard === undefined) { throw new Error('Snowboard must be loaded in order to use the extra plugins.'); @@ -18,4 +19,5 @@ if (window.Snowboard === undefined) { Snowboard.addPlugin('flash', Flash); Snowboard.addPlugin('attachLoading', AttachLoading); Snowboard.addPlugin('stripeLoader', StripeLoader); + Snowboard.addPlugin('trigger', Trigger); })(window.Snowboard); diff --git a/modules/system/assets/ui/js/input.trigger.js b/modules/system/assets/ui/js/input.trigger.js deleted file mode 100644 index e9403497a2..0000000000 --- a/modules/system/assets/ui/js/input.trigger.js +++ /dev/null @@ -1,195 +0,0 @@ -/* - * The trigger API - * - * - Documentation: ../docs/input-trigger.md - */ -+function ($) { "use strict"; - - var TriggerOn = function (element, options) { - - var $el = this.$el = $(element); - - this.options = options || {}; - - if (this.options.triggerCondition === false) - throw new Error('Trigger condition is not specified.') - - if (this.options.trigger === false) - throw new Error('Trigger selector is not specified.') - - if (this.options.triggerAction === false) - throw new Error('Trigger action is not specified.') - - this.triggerCondition = this.options.triggerCondition - - if (this.options.triggerCondition.indexOf('value') == 0) { - var match = this.options.triggerCondition.match(/[^[\]]+(?=])/g) - this.triggerCondition = 'value' - this.triggerConditionValue = (match) ? match : [""] - } - - this.triggerParent = undefined - if (this.options.triggerClosestParent !== undefined) { - var closestParentElements = this.options.triggerClosestParent.split(',') - for (var i = 0; i < closestParentElements.length; i++) { - var $triggerElement = $el.closest(closestParentElements[i]) - if ($triggerElement.length) { - this.triggerParent = $triggerElement - break - } - } - } - - if ( - this.triggerCondition == 'checked' || - this.triggerCondition == 'unchecked' || - this.triggerCondition == 'value' - ) { - $(document).on('change', this.options.trigger, $.proxy(this.onConditionChanged, this)) - } - - var self = this - $el.on('oc.triggerOn.update', function(e){ - e.stopPropagation() - self.onConditionChanged() - }) - - self.onConditionChanged() - } - - TriggerOn.prototype.onConditionChanged = function() { - if (this.triggerCondition == 'checked') { - this.updateTarget(!!$(this.options.trigger + ':checked', this.triggerParent).length) - } - else if (this.triggerCondition == 'unchecked') { - this.updateTarget(!$(this.options.trigger + ':checked', this.triggerParent).length) - } - else if (this.triggerCondition == 'value') { - var trigger, triggered = false - - trigger = $(this.options.trigger, this.triggerParent) - .not('input[type=checkbox], input[type=radio], input[type=button], input[type=submit]') - - if (!trigger.length) { - trigger = $(this.options.trigger, this.triggerParent) - .not(':not(input[type=checkbox]:checked, input[type=radio]:checked)') - } - - var self = this - trigger.each(function() { - var triggerValue = $(this).val(); - - $.each($.isArray(triggerValue) ? triggerValue : [triggerValue], function(key, val) { - triggered = $.inArray(val, self.triggerConditionValue) != -1 - return !triggered - }) - - return !triggered - }) - - this.updateTarget(triggered) - } - } - - TriggerOn.prototype.updateTarget = function(status) { - var self = this, - actions = this.options.triggerAction.split('|') - - $.each(actions, function(index, action) { - self.updateTargetAction(action, status) - }) - - $(window).trigger('resize') - - this.$el.trigger('oc.triggerOn.afterUpdate', status) - } - - TriggerOn.prototype.updateTargetAction = function(action, status) { - if (action == 'show') { - this.$el - .toggleClass('hide', !status) - .trigger('hide.oc.triggerapi', [!status]) - } - else if (action == 'hide') { - this.$el - .toggleClass('hide', status) - .trigger('hide.oc.triggerapi', [status]) - } - else if (action == 'enable') { - this.$el - .prop('disabled', !status) - .toggleClass('control-disabled', !status) - .trigger('disable.oc.triggerapi', [!status]) - } - else if (action == 'disable') { - this.$el - .prop('disabled', status) - .toggleClass('control-disabled', status) - .trigger('disable.oc.triggerapi', [status]) - } - else if (action == 'empty' && status) { - this.$el - .not('input[type=checkbox], input[type=radio], input[type=button], input[type=submit]') - .val('') - - this.$el - .not(':not(input[type=checkbox], input[type=radio])') - .prop('checked', false) - - this.$el - .trigger('empty.oc.triggerapi') - .trigger('change') - } - - if (action == 'show' || action == 'hide') { - this.fixButtonClasses() - } - } - - TriggerOn.prototype.fixButtonClasses = function() { - var group = this.$el.closest('.btn-group') - - if (group.length > 0 && this.$el.is(':last-child')) - this.$el.prev().toggleClass('last', this.$el.hasClass('hide')) - } - - TriggerOn.DEFAULTS = { - triggerAction: false, - triggerCondition: false, - triggerClosestParent: undefined, - trigger: false - } - - // TRIGGERON PLUGIN DEFINITION - // ============================ - - var old = $.fn.triggerOn - - $.fn.triggerOn = function (option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('oc.triggerOn') - var options = $.extend({}, TriggerOn.DEFAULTS, $this.data(), typeof option == 'object' && option) - - if (!data) $this.data('oc.triggerOn', (data = new TriggerOn(this, options))) - }) - } - - $.fn.triggerOn.Constructor = TriggerOn - - // TRIGGERON NO CONFLICT - // ================= - - $.fn.triggerOn.noConflict = function () { - $.fn.triggerOn = old - return this - } - - // TRIGGERON DATA-API - // =============== - - $(document).render(function(){ - $('[data-trigger]').triggerOn() - }) - -}(window.jQuery); diff --git a/modules/system/assets/ui/storm-min.js b/modules/system/assets/ui/storm-min.js index c685b14eba..47641381bb 100644 --- a/modules/system/assets/ui/storm-min.js +++ b/modules/system/assets/ui/storm-min.js @@ -2591,46 +2591,7 @@ if(!data)$this.data('oc.inputPreset',(data=new InputPreset(this,options)))})} $.fn.inputPreset.Constructor=InputPreset $.fn.inputPreset.noConflict=function(){$.fn.inputPreset=old return this} -$(document).render(function(){$('[data-input-preset]').inputPreset()})}(window.jQuery);+function($){"use strict";var TriggerOn=function(element,options){var $el=this.$el=$(element);this.options=options||{};if(this.options.triggerCondition===false)throw new Error('Trigger condition is not specified.') -if(this.options.trigger===false)throw new Error('Trigger selector is not specified.') -if(this.options.triggerAction===false)throw new Error('Trigger action is not specified.') -this.triggerCondition=this.options.triggerCondition -if(this.options.triggerCondition.indexOf('value')==0){var match=this.options.triggerCondition.match(/[^[\]]+(?=])/g) -this.triggerCondition='value' -this.triggerConditionValue=(match)?match:[""]}this.triggerParent=undefined -if(this.options.triggerClosestParent!==undefined){var closestParentElements=this.options.triggerClosestParent.split(',') -for(var i=0;i0&&this.$el.is(':last-child'))this.$el.prev().toggleClass('last',this.$el.hasClass('hide'))} -TriggerOn.DEFAULTS={triggerAction:false,triggerCondition:false,triggerClosestParent:undefined,trigger:false} -var old=$.fn.triggerOn -$.fn.triggerOn=function(option){return this.each(function(){var $this=$(this) -var data=$this.data('oc.triggerOn') -var options=$.extend({},TriggerOn.DEFAULTS,$this.data(),typeof option=='object'&&option) -if(!data)$this.data('oc.triggerOn',(data=new TriggerOn(this,options)))})} -$.fn.triggerOn.Constructor=TriggerOn -$.fn.triggerOn.noConflict=function(){$.fn.triggerOn=old -return this} -$(document).render(function(){$('[data-trigger]').triggerOn()})}(window.jQuery);+function($){"use strict";var DragValue=function(element,options){this.options=options +$(document).render(function(){$('[data-input-preset]').inputPreset()})}(window.jQuery);+function($){"use strict";var DragValue=function(element,options){this.options=options this.$el=$(element) this.init()} DragValue.DEFAULTS={dragClick:false} diff --git a/modules/system/assets/ui/storm.js b/modules/system/assets/ui/storm.js index 8f66eaa4f7..084fb8db89 100644 --- a/modules/system/assets/ui/storm.js +++ b/modules/system/assets/ui/storm.js @@ -57,7 +57,6 @@ =require js/input.monitor.js =require js/input.hotkey.js =require js/input.preset.js -=require js/input.trigger.js =require js/drag.value.js =require js/drag.sort.js =require js/drag.scroll.js diff --git a/package.json b/package.json index 4fb76141ed..b0b665808d 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "workspaces": { "packages": [ "modules/backend", - "modules/system" + "modules/system", + "themes/workshop" ] } -} +} \ No newline at end of file