abyme 0.6.6 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/dist/abyme.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("stimulus")):"function"==typeof define&&define.amd?define(["exports","stimulus"],t):t((e||self).abyme={},e.Stimulus)}(this,function(e,t){function n(e,t){return n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},n(e,t)}function i(e,t,n){if(!e.s){if(n instanceof o){if(!n.s)return void(n.o=i.bind(null,e,t));1&t&&(t=n.s),n=n.v}if(n&&n.then)return void n.then(i.bind(null,e,t),i.bind(null,e,2));e.s=t,e.v=n;var r=e.o;r&&r(e)}}var r=function(e){var t,r;function s(){return e.apply(this,arguments)||this}r=e,(t=s).prototype=Object.create(r.prototype),t.prototype.constructor=t,n(t,r);var f,u,c=s.prototype;return c.connect=function(){console.log("Abyme Connected"),this.count&&this.add_default_associations()},c.add_association=function(e){if(e&&e.preventDefault(),this.element.dataset.limit&&this.limit_check())return this.create_event("limit-reached"),!1;var t=this.build_html();this.create_event("before-add"),this.associationsTarget.insertAdjacentHTML(this.position,t),this.create_event("after-add")},c.remove_association=function(e){e.preventDefault(),this.create_event("before-remove"),this.mark_for_destroy(e),this.create_event("after-remove")},c.create_event=function(e,t){void 0===t&&(t=null);var n=new CustomEvent("abyme:"+e,{detail:{controller:this,content:t}});this.element.dispatchEvent(n),this.dispatch(n,e)},c.dispatch=function(e,t){"before-add"===t&&this.abymeBeforeAdd&&this.abymeBeforeAdd(e),"after-add"===t&&this.abymeAfterAdd&&this.abymeAfterAdd(e),"before-remove"===t&&this.abymeBeforeRemove&&this.abymeBeforeAdd(e),"after-remove"===t&&this.abymeAfterRemove&&this.abymeAfterRemove(e)},c.abymeBeforeAdd=function(e){},c.abymeAfterAdd=function(e){},c.abymeBeforeRemove=function(e){},c.abymeAfterRemove=function(e){},c.build_html=function(){var e=this.templateTarget.innerHTML.replace(/NEW_RECORD/g,(new Date).getTime());if(e.match(/<template[\s\S]+<\/template>/)){var t=e.match(/<template[\s\S]+<\/template>/)[0].replace(/(\[\d{12,}\])(\[[^\[\]]+\]"){1}/g,"[NEW_RECORD]$2");e=e.replace(/<template[\s\S]+<\/template>/g,t)}return e},c.mark_for_destroy=function(e){var t=e.target.closest(".abyme--fields");t.querySelector("input[name*='_destroy']").value=1,t.style.display="none",t.classList.add("abyme--marked-for-destroy")},c.limit_check=function(){return this.newFieldsTargets.filter(function(e){return!e.classList.contains("abyme--marked-for-destroy")}).length>=parseInt(this.element.dataset.limit)},c.add_default_associations=function(){try{var e=this,t=0,n=function(e,t,n){for(var r;;){var s=e();if(a(s)&&(s=s.v),!s)return f;if(s.then){r=0;break}var f=n();if(f&&f.then){if(!a(f)){r=1;break}f=f.s}}var u=new o,c=i.bind(null,u,2);return(0===r?s.then(l):1===r?f.then(d):(void 0).then(function(){(s=e())?s.then?s.then(l).then(void 0,c):l(s):i(u,1,f)})).then(void 0,c),u;function d(t){f=t;do{if(!(s=e())||a(s)&&!s.v)return void i(u,1,f);if(s.then)return void s.then(l).then(void 0,c);a(f=n())&&(f=f.v)}while(!f||!f.then);f.then(d).then(void 0,c)}function l(e){e?(f=n())&&f.then?f.then(d).then(void 0,c):d(f):i(u,1,f)}}(function(){return t<e.count},0,function(){return e.add_association(),t++,Promise.resolve(e.sleep(1)).then(function(){})});return Promise.resolve(n&&n.then?n.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},c.sleep=function(e){return new Promise(function(t){return setTimeout(t,e)})},f=s,(u=[{key:"count",get:function(){return this.element.dataset.minCount||0}},{key:"position",get:function(){return"end"===this.associationsTarget.dataset.abymePosition?"beforeend":"afterbegin"}}])&&function(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}(f.prototype,u),Object.defineProperty(f,"prototype",{writable:!1}),s}(t.Controller),o=function(){function e(){}return e.prototype.then=function(t,n){var r=new e,o=this.s;if(o){var a=1&o?t:n;if(a){try{i(r,1,a(this.v))}catch(e){i(r,2,e)}return r}return this}return this.o=function(e){try{var o=e.v;1&e.s?i(r,1,t?t(o):o):n?i(r,1,n(o)):i(r,2,o)}catch(e){i(r,2,e)}},r},e}();function a(e){return e instanceof o&&1&e.s}r.targets=["template","associations","fields","newFields"],e.AbymeController=r});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e||self).abyme={})}(this,function(e){function t(e,r){return t=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},t(e,r)}function r(e){return e.replace(/(?:[_-])([a-z0-9])/g,(e,t)=>t.toUpperCase())}function n(e){return e.charAt(0).toUpperCase()+e.slice(1)}function o(e,t){const r=i(e);return Array.from(r.reduce((e,r)=>(function(e,t){const r=e[t];return Array.isArray(r)?r:[]}(r,t).forEach(t=>e.add(t)),e),new Set))}function i(e){const t=[];for(;e;)t.push(e),e=Object.getPrototypeOf(e);return t.reverse()}function s(e){return e.reduce((e,[t,r])=>Object.assign(Object.assign({},e),{[t]:r}),{})}function a([e,t],n){return function(e){const t=`${o=e.token,o.replace(/([A-Z])/g,(e,t)=>`-${t.toLowerCase()}`)}-value`,n=function(e){const t=function(e){const t=c(e.typeObject.type);if(!t)return;const r=u(e.typeObject.default);if(t!==r)throw new Error(`The specified default value for the Stimulus Value "${e.controller?`${e.controller}.${e.token}`:e.token}" must match the defined type "${t}". The provided default value of "${e.typeObject.default}" is of type "${r}".`);return t}({controller:e.controller,token:e.token,typeObject:e.typeDefinition}),r=u(e.typeDefinition),n=c(e.typeDefinition),o=t||r||n;if(o)return o;throw new Error(`Unknown value type "${e.controller?`${e.controller}.${e.typeDefinition}`:e.token}" for "${e.token}" value`)}(e);var o;return{type:n,key:t,name:r(t),get defaultValue(){return function(e){const t=c(e);if(t)return l[t];const r=e.default;return void 0!==r?r:e}(e.typeDefinition)},get hasCustomDefaultValue(){return void 0!==u(e.typeDefinition)},reader:f[n],writer:d[n]||d.default}}({controller:n,token:e,typeDefinition:t})}function c(e){switch(e){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function u(e){switch(typeof e){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(e)?"array":"[object Object]"===Object.prototype.toString.call(e)?"object":void 0}(()=>{try{!function(){const e=function(e){function t(){return Reflect.construct(e,arguments,new.target)}return t.prototype=Object.create(e.prototype,{constructor:{value:t}}),Reflect.setPrototypeOf(t,e),t}(function(){this.a.call(this)});e.prototype.a=function(){},new e}()}catch(e){return e=>class extends e{}}})(),Object.assign(Object.assign({enter:"Enter",tab:"Tab",esc:"Escape",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End"},s("abcdefghijklmnopqrstuvwxyz".split("").map(e=>[e,e]))),s("0123456789".split("").map(e=>[e,e])));const l={get array(){return[]},boolean:!1,number:0,get object(){return{}},string:""},f={array(e){const t=JSON.parse(e);if(!Array.isArray(t))throw new TypeError(`expected value of type "array" but instead got value "${e}" of type "${u(t)}"`);return t},boolean:e=>!("0"==e||"false"==String(e).toLowerCase()),number:e=>Number(e),object(e){const t=JSON.parse(e);if(null===t||"object"!=typeof t||Array.isArray(t))throw new TypeError(`expected value of type "object" but instead got value "${e}" of type "${u(t)}"`);return t},string:e=>e},d={default:function(e){return`${e}`},array:h,object:h};function h(e){return JSON.stringify(e)}class p{constructor(e){this.context=e}static get shouldLoad(){return!0}static afterLoad(e,t){}get application(){return this.context.application}get scope(){return this.context.scope}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get targets(){return this.scope.targets}get outlets(){return this.scope.outlets}get classes(){return this.scope.classes}get data(){return this.scope.data}initialize(){}connect(){}disconnect(){}dispatch(e,{target:t=this.element,detail:r={},prefix:n=this.identifier,bubbles:o=!0,cancelable:i=!0}={}){const s=new CustomEvent(n?`${n}:${e}`:e,{detail:r,bubbles:o,cancelable:i});return t.dispatchEvent(s),s}}function m(e,t,r){if(!e.s){if(r instanceof y){if(!r.s)return void(r.o=m.bind(null,e,t));1&t&&(t=r.s),r=r.v}if(r&&r.then)return void r.then(m.bind(null,e,t),m.bind(null,e,2));e.s=t,e.v=r;var n=e.o;n&&n(e)}}p.blessings=[function(e){return o(e,"classes").reduce((e,t)=>{return Object.assign(e,{[`${r=t}Class`]:{get(){const{classes:e}=this;if(e.has(r))return e.get(r);{const t=e.getAttributeName(r);throw new Error(`Missing attribute "${t}"`)}}},[`${r}Classes`]:{get(){return this.classes.getAll(r)}},[`has${n(r)}Class`]:{get(){return this.classes.has(r)}}});var r},{})},function(e){return o(e,"targets").reduce((e,t)=>{return Object.assign(e,{[`${r=t}Target`]:{get(){const e=this.targets.find(r);if(e)return e;throw new Error(`Missing target element "${r}" for "${this.identifier}" controller`)}},[`${r}Targets`]:{get(){return this.targets.findAll(r)}},[`has${n(r)}Target`]:{get(){return this.targets.has(r)}}});var r},{})},function(e){const t=function(e,t){return i(e).reduce((e,t)=>(e.push(...function(e,t){const r=e.values;return r?Object.keys(r).map(e=>[e,r[e]]):[]}(t)),e),[])}(e),r={valueDescriptorMap:{get(){return t.reduce((e,t)=>{const r=a(t,this.identifier),n=this.data.getAttributeNameForKey(r.key);return Object.assign(e,{[n]:r})},{})}}};return t.reduce((e,t)=>Object.assign(e,function(e,t){const r=a(e,void 0),{key:o,name:i,reader:s,writer:c}=r;return{[i]:{get(){const e=this.data.get(o);return null!==e?s(e):r.defaultValue},set(e){void 0===e?this.data.delete(o):this.data.set(o,c(e))}},[`has${n(i)}`]:{get(){return this.data.has(o)||r.hasCustomDefaultValue}}}}(t)),r)},function(e){return o(e,"outlets").reduce((e,t)=>Object.assign(e,function(e){const t=r(e.replace(/--/g,"-").replace(/__/g,"_"));return{[`${t}Outlet`]:{get(){const t=this.outlets.find(e);if(t){const r=this.application.getControllerForElementAndIdentifier(t,e);if(r)return r;throw new Error(`Missing "data-controller=${e}" attribute on outlet element for "${this.identifier}" controller`)}throw new Error(`Missing outlet element "${e}" for "${this.identifier}" controller`)}},[`${t}Outlets`]:{get(){const t=this.outlets.findAll(e);return t.length>0?t.map(t=>{const r=this.application.getControllerForElementAndIdentifier(t,e);if(r)return r;console.warn(`The provided outlet element is missing the outlet controller "${e}" for "${this.identifier}"`,t)}).filter(e=>e):[]}},[`${t}OutletElement`]:{get(){const t=this.outlets.find(e);if(t)return t;throw new Error(`Missing outlet element "${e}" for "${this.identifier}" controller`)}},[`${t}OutletElements`]:{get(){return this.outlets.findAll(e)}},[`has${n(t)}Outlet`]:{get(){return this.outlets.has(e)}}}}(t)),{})}],p.targets=[],p.outlets=[],p.values={};var b=function(e){var r,n;function o(){return e.apply(this,arguments)||this}n=e,(r=o).prototype=Object.create(n.prototype),r.prototype.constructor=r,t(r,n);var i,s,a=o.prototype;return a.connect=function(){console.log("Abyme Connected"),this.count&&this.add_default_associations()},a.add_association=function(e){if(e&&e.preventDefault(),this.element.dataset.limit&&this.limit_check())return this.create_event("limit-reached"),!1;var t=this.build_html();this.create_event("before-add"),this.associationsTarget.insertAdjacentHTML(this.position,t),this.create_event("after-add")},a.remove_association=function(e){e.preventDefault(),this.create_event("before-remove"),this.mark_for_destroy(e),this.create_event("after-remove")},a.create_event=function(e,t){void 0===t&&(t=null);var r=new CustomEvent("abyme:"+e,{detail:{controller:this,content:t}});this.element.dispatchEvent(r),this.dispatch(r,e)},a.dispatch=function(e,t){"before-add"===t&&this.abymeBeforeAdd&&this.abymeBeforeAdd(e),"after-add"===t&&this.abymeAfterAdd&&this.abymeAfterAdd(e),"before-remove"===t&&this.abymeBeforeRemove&&this.abymeBeforeAdd(e),"after-remove"===t&&this.abymeAfterRemove&&this.abymeAfterRemove(e)},a.abymeBeforeAdd=function(e){},a.abymeAfterAdd=function(e){},a.abymeBeforeRemove=function(e){},a.abymeAfterRemove=function(e){},a.build_html=function(){var e=this.templateTarget.innerHTML.replace(/NEW_RECORD/g,(new Date).getTime());if(e.match(/<template[\s\S]+<\/template>/)){var t=e.match(/<template[\s\S]+<\/template>/)[0].replace(/(\[\d{12,}\])(\[[^\[\]]+\]"){1}/g,"[NEW_RECORD]$2");e=e.replace(/<template[\s\S]+<\/template>/g,t)}return e},a.mark_for_destroy=function(e){var t=e.target.closest(".abyme--fields");t.querySelector("input[name*='_destroy']").value=1,t.style.display="none",t.classList.add("abyme--marked-for-destroy")},a.limit_check=function(){return this.newFieldsTargets.filter(function(e){return!e.classList.contains("abyme--marked-for-destroy")}).length>=parseInt(this.element.dataset.limit)},a.add_default_associations=function(){try{var e=this,t=0,r=function(e,t,r){for(var n;;){var o=e();if(g(o)&&(o=o.v),!o)return i;if(o.then){n=0;break}var i=r();if(i&&i.then){if(!g(i)){n=1;break}i=i.s}}var s=new y,a=m.bind(null,s,2);return(0===n?o.then(u):1===n?i.then(c):(void 0).then(function(){(o=e())?o.then?o.then(u).then(void 0,a):u(o):m(s,1,i)})).then(void 0,a),s;function c(t){i=t;do{if(!(o=e())||g(o)&&!o.v)return void m(s,1,i);if(o.then)return void o.then(u).then(void 0,a);g(i=r())&&(i=i.v)}while(!i||!i.then);i.then(c).then(void 0,a)}function u(e){e?(i=r())&&i.then?i.then(c).then(void 0,a):c(i):m(s,1,i)}}(function(){return t<e.count},0,function(){return e.add_association(),t++,Promise.resolve(e.sleep(1)).then(function(){})});return Promise.resolve(r&&r.then?r.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},a.sleep=function(e){return new Promise(function(t){return setTimeout(t,e)})},i=o,(s=[{key:"count",get:function(){return this.element.dataset.minCount||0}},{key:"position",get:function(){return"end"===this.associationsTarget.dataset.abymePosition?"beforeend":"afterbegin"}}])&&function(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}(i.prototype,s),Object.defineProperty(i,"prototype",{writable:!1}),o}(p),y=function(){function e(){}return e.prototype.then=function(t,r){var n=new e,o=this.s;if(o){var i=1&o?t:r;if(i){try{m(n,1,i(this.v))}catch(e){m(n,2,e)}return n}return this}return this.o=function(e){try{var o=e.v;1&e.s?m(n,1,t?t(o):o):r?m(n,1,r(o)):m(n,2,o)}catch(e){m(n,2,e)}},n},e}();function g(e){return e instanceof y&&1&e.s}b.targets=["template","associations","fields","newFields"],e.AbymeController=b});
2
2
  //# sourceMappingURL=abyme.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"abyme.umd.js","sources":["../src/abyme_controller.js"],"sourcesContent":["import { Controller } from 'stimulus';\n\nexport default class extends Controller {\n // static targets = ['template', 'associations', 'fields', 'newFields'];\n // Some applications don't compile correctly with the usual static syntax. \n // Thus implementing targets with standard getters below\n\n static targets = ['template', 'associations', 'fields', 'newFields']\n\n connect() {\n console.log(\"Abyme Connected\")\n\n if (this.count) {\n // If data-count is present,\n // add n default fields on page load\n\n this.add_default_associations();\n }\n }\n\n // return the value of the data-count attribute\n\n get count() {\n return this.element.dataset.minCount || 0;\n }\n \n // return the value of the data-position attribute\n // if there is no position specified set end as default\n\n get position() {\n return this.associationsTarget.dataset.abymePosition === 'end' ? 'beforeend' : 'afterbegin';\n }\n\n // ADD_ASSOCIATION\n\n // this function is call whenever a click occurs\n // on the element with the click->abyme#add_association\n // <button> element by default\n\n // if a data-count is present the add_association\n // will be call without an event so we have to check\n // this case\n\n // check for limit reached \n // dispatch an event if the limit is reached\n\n // - call the function build_html that take care\n // for building the correct html to be inserted in the DOM\n // - dispatch an event before insert\n // - insert html into the dom\n // - dispatch an event after insert\n\n add_association(event) {\n if (event) {\n event.preventDefault();\n }\n\n if (this.element.dataset.limit && this.limit_check()) {\n this.create_event('limit-reached')\n return false\n }\n\n const html = this.build_html();\n this.create_event('before-add');\n this.associationsTarget.insertAdjacentHTML(this.position, html);\n this.create_event('after-add');\n }\n\n // REMOVE_ASSOCIATION\n\n // this function is call whenever a click occurs\n // on the element with the click->abyme#remove_association\n // <button> element by default\n\n // - call the function mark_for_destroy that takes care\n // of marking the element for destruction and hiding it\n // - dispatch an event before mark & hide\n // - mark for descrution + hide the element\n // - dispatch an event after mark and hide\n\n remove_association(event) {\n event.preventDefault();\n\n this.create_event('before-remove');\n this.mark_for_destroy(event);\n this.create_event('after-remove');\n }\n\n // LIFECYCLE EVENTS RELATED\n\n // CREATE_EVENT\n\n // take a stage (String) => before-add, after-add...\n // create a new custom event \n // and dispatch at at the controller level\n\n create_event(stage, html = null) {\n const event = new CustomEvent(`abyme:${stage}`, { detail: {controller: this, content: html} });\n this.element.dispatchEvent(event);\n // WIP\n this.dispatch(event, stage);\n }\n\n // WIP : Trying to integrate event handling through controller inheritance\n dispatch(event, stage) {\n if (stage === 'before-add' && this.abymeBeforeAdd) this.abymeBeforeAdd(event);\n if (stage === 'after-add' && this.abymeAfterAdd) this.abymeAfterAdd(event);\n if (stage === 'before-remove' && this.abymeBeforeRemove) this.abymeBeforeAdd(event);\n if (stage === 'after-remove' && this.abymeAfterRemove) this.abymeAfterRemove(event);\n }\n\n abymeBeforeAdd(event) {\n }\n\n abymeAfterAdd(event) {\n }\n\n abymeBeforeRemove(event) {\n }\n\n abymeAfterRemove(event) {\n }\n\n // BUILD HTML\n\n // takes the html template and substitutes the sub-string\n // NEW_RECORD for a generated timestamp\n // then if there is a sub template in the html (multiple nested level)\n // set all the sub timestamps back as NEW_RECORD\n // finally returns the html \n\n build_html() {\n let html = this.templateTarget.innerHTML.replace(\n /NEW_RECORD/g,\n new Date().getTime()\n );\n \n if (html.match(/<template[\\s\\S]+<\\/template>/)) {\n const template = html\n .match(/<template[\\s\\S]+<\\/template>/)[0]\n .replace(/(\\[\\d{12,}\\])(\\[[^\\[\\]]+\\]\"){1}/g, `[NEW_RECORD]$2`);\n \n html = html.replace(/<template[\\s\\S]+<\\/template>/g, template);\n }\n\n return html;\n }\n \n // MARK_FOR_DESTROY\n\n // mark association for destruction\n // get the closest abyme--fields from the remove_association button\n // set the _destroy input value as 1\n // hide the element\n // add the class of abyme--marked-for-destroy to the element\n\n mark_for_destroy(event) {\n let item = event.target.closest('.abyme--fields');\n item.querySelector(\"input[name*='_destroy']\").value = 1;\n item.style.display = 'none';\n item.classList.add('abyme--marked-for-destroy')\n }\n\n\n // LIMIT_CHECK\n\n // Check if associations limit is reached\n // based on newFieldsTargets only\n // persisted fields are ignored\n\n limit_check() {\n return (this.newFieldsTargets\n .filter(item => !item.classList.contains('abyme--marked-for-destroy'))).length \n >= parseInt(this.element.dataset.limit)\n }\n\n // ADD_DEFAULT_ASSOCIATION\n\n // Add n default blank associations at page load\n // call sleep function to ensure uniqueness of timestamp\n\n async add_default_associations() {\n let i = 0\n while (i < this.count) {\n this.add_association()\n i++\n await this.sleep(1);\n }\n }\n\n sleep(ms) {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n}\n"],"names":["_settle","pact","state","value","s","_Pact","o","bind","v","then","observer","connect","console","log","this","count","add_default_associations","add_association","event","preventDefault","element","dataset","limit","limit_check","create_event","html","build_html","associationsTarget","insertAdjacentHTML","position","remove_association","mark_for_destroy","stage","CustomEvent","detail","controller","content","dispatchEvent","dispatch","abymeBeforeAdd","abymeAfterAdd","abymeBeforeRemove","abymeAfterRemove","templateTarget","innerHTML","replace","Date","getTime","match","template","item","target","closest","querySelector","style","display","classList","add","newFieldsTargets","filter","contains","length","parseInt","i","test","update","body","shouldContinue","_isSettledPact","result","reject","_resumeAfterTest","_resumeAfterBody","updateValue","_this2","sleep","ms","Promise","resolve","setTimeout","minCount","abymePosition","Controller","prototype","onFulfilled","onRejected","callback","e","_this","thenable","targets"],"mappings":"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"}
1
+ {"version":3,"file":"abyme.umd.js","sources":["../node_modules/@hotwired/stimulus/dist/stimulus.js","../src/abyme_controller.js"],"sourcesContent":["/*\nStimulus 3.2.1\nCopyright © 2022 Basecamp, LLC\n */\nclass EventListener {\n constructor(eventTarget, eventName, eventOptions) {\n this.eventTarget = eventTarget;\n this.eventName = eventName;\n this.eventOptions = eventOptions;\n this.unorderedBindings = new Set();\n }\n connect() {\n this.eventTarget.addEventListener(this.eventName, this, this.eventOptions);\n }\n disconnect() {\n this.eventTarget.removeEventListener(this.eventName, this, this.eventOptions);\n }\n bindingConnected(binding) {\n this.unorderedBindings.add(binding);\n }\n bindingDisconnected(binding) {\n this.unorderedBindings.delete(binding);\n }\n handleEvent(event) {\n const extendedEvent = extendEvent(event);\n for (const binding of this.bindings) {\n if (extendedEvent.immediatePropagationStopped) {\n break;\n }\n else {\n binding.handleEvent(extendedEvent);\n }\n }\n }\n hasBindings() {\n return this.unorderedBindings.size > 0;\n }\n get bindings() {\n return Array.from(this.unorderedBindings).sort((left, right) => {\n const leftIndex = left.index, rightIndex = right.index;\n return leftIndex < rightIndex ? -1 : leftIndex > rightIndex ? 1 : 0;\n });\n }\n}\nfunction extendEvent(event) {\n if (\"immediatePropagationStopped\" in event) {\n return event;\n }\n else {\n const { stopImmediatePropagation } = event;\n return Object.assign(event, {\n immediatePropagationStopped: false,\n stopImmediatePropagation() {\n this.immediatePropagationStopped = true;\n stopImmediatePropagation.call(this);\n },\n });\n }\n}\n\nclass Dispatcher {\n constructor(application) {\n this.application = application;\n this.eventListenerMaps = new Map();\n this.started = false;\n }\n start() {\n if (!this.started) {\n this.started = true;\n this.eventListeners.forEach((eventListener) => eventListener.connect());\n }\n }\n stop() {\n if (this.started) {\n this.started = false;\n this.eventListeners.forEach((eventListener) => eventListener.disconnect());\n }\n }\n get eventListeners() {\n return Array.from(this.eventListenerMaps.values()).reduce((listeners, map) => listeners.concat(Array.from(map.values())), []);\n }\n bindingConnected(binding) {\n this.fetchEventListenerForBinding(binding).bindingConnected(binding);\n }\n bindingDisconnected(binding, clearEventListeners = false) {\n this.fetchEventListenerForBinding(binding).bindingDisconnected(binding);\n if (clearEventListeners)\n this.clearEventListenersForBinding(binding);\n }\n handleError(error, message, detail = {}) {\n this.application.handleError(error, `Error ${message}`, detail);\n }\n clearEventListenersForBinding(binding) {\n const eventListener = this.fetchEventListenerForBinding(binding);\n if (!eventListener.hasBindings()) {\n eventListener.disconnect();\n this.removeMappedEventListenerFor(binding);\n }\n }\n removeMappedEventListenerFor(binding) {\n const { eventTarget, eventName, eventOptions } = binding;\n const eventListenerMap = this.fetchEventListenerMapForEventTarget(eventTarget);\n const cacheKey = this.cacheKey(eventName, eventOptions);\n eventListenerMap.delete(cacheKey);\n if (eventListenerMap.size == 0)\n this.eventListenerMaps.delete(eventTarget);\n }\n fetchEventListenerForBinding(binding) {\n const { eventTarget, eventName, eventOptions } = binding;\n return this.fetchEventListener(eventTarget, eventName, eventOptions);\n }\n fetchEventListener(eventTarget, eventName, eventOptions) {\n const eventListenerMap = this.fetchEventListenerMapForEventTarget(eventTarget);\n const cacheKey = this.cacheKey(eventName, eventOptions);\n let eventListener = eventListenerMap.get(cacheKey);\n if (!eventListener) {\n eventListener = this.createEventListener(eventTarget, eventName, eventOptions);\n eventListenerMap.set(cacheKey, eventListener);\n }\n return eventListener;\n }\n createEventListener(eventTarget, eventName, eventOptions) {\n const eventListener = new EventListener(eventTarget, eventName, eventOptions);\n if (this.started) {\n eventListener.connect();\n }\n return eventListener;\n }\n fetchEventListenerMapForEventTarget(eventTarget) {\n let eventListenerMap = this.eventListenerMaps.get(eventTarget);\n if (!eventListenerMap) {\n eventListenerMap = new Map();\n this.eventListenerMaps.set(eventTarget, eventListenerMap);\n }\n return eventListenerMap;\n }\n cacheKey(eventName, eventOptions) {\n const parts = [eventName];\n Object.keys(eventOptions)\n .sort()\n .forEach((key) => {\n parts.push(`${eventOptions[key] ? \"\" : \"!\"}${key}`);\n });\n return parts.join(\":\");\n }\n}\n\nconst defaultActionDescriptorFilters = {\n stop({ event, value }) {\n if (value)\n event.stopPropagation();\n return true;\n },\n prevent({ event, value }) {\n if (value)\n event.preventDefault();\n return true;\n },\n self({ event, value, element }) {\n if (value) {\n return element === event.target;\n }\n else {\n return true;\n }\n },\n};\nconst descriptorPattern = /^(?:(.+?)(?:\\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;\nfunction parseActionDescriptorString(descriptorString) {\n const source = descriptorString.trim();\n const matches = source.match(descriptorPattern) || [];\n let eventName = matches[1];\n let keyFilter = matches[2];\n if (keyFilter && ![\"keydown\", \"keyup\", \"keypress\"].includes(eventName)) {\n eventName += `.${keyFilter}`;\n keyFilter = \"\";\n }\n return {\n eventTarget: parseEventTarget(matches[3]),\n eventName,\n eventOptions: matches[6] ? parseEventOptions(matches[6]) : {},\n identifier: matches[4],\n methodName: matches[5],\n keyFilter,\n };\n}\nfunction parseEventTarget(eventTargetName) {\n if (eventTargetName == \"window\") {\n return window;\n }\n else if (eventTargetName == \"document\") {\n return document;\n }\n}\nfunction parseEventOptions(eventOptions) {\n return eventOptions\n .split(\":\")\n .reduce((options, token) => Object.assign(options, { [token.replace(/^!/, \"\")]: !/^!/.test(token) }), {});\n}\nfunction stringifyEventTarget(eventTarget) {\n if (eventTarget == window) {\n return \"window\";\n }\n else if (eventTarget == document) {\n return \"document\";\n }\n}\n\nfunction camelize(value) {\n return value.replace(/(?:[_-])([a-z0-9])/g, (_, char) => char.toUpperCase());\n}\nfunction namespaceCamelize(value) {\n return camelize(value.replace(/--/g, \"-\").replace(/__/g, \"_\"));\n}\nfunction capitalize(value) {\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\nfunction dasherize(value) {\n return value.replace(/([A-Z])/g, (_, char) => `-${char.toLowerCase()}`);\n}\nfunction tokenize(value) {\n return value.match(/[^\\s]+/g) || [];\n}\n\nclass Action {\n constructor(element, index, descriptor, schema) {\n this.element = element;\n this.index = index;\n this.eventTarget = descriptor.eventTarget || element;\n this.eventName = descriptor.eventName || getDefaultEventNameForElement(element) || error(\"missing event name\");\n this.eventOptions = descriptor.eventOptions || {};\n this.identifier = descriptor.identifier || error(\"missing identifier\");\n this.methodName = descriptor.methodName || error(\"missing method name\");\n this.keyFilter = descriptor.keyFilter || \"\";\n this.schema = schema;\n }\n static forToken(token, schema) {\n return new this(token.element, token.index, parseActionDescriptorString(token.content), schema);\n }\n toString() {\n const eventFilter = this.keyFilter ? `.${this.keyFilter}` : \"\";\n const eventTarget = this.eventTargetName ? `@${this.eventTargetName}` : \"\";\n return `${this.eventName}${eventFilter}${eventTarget}->${this.identifier}#${this.methodName}`;\n }\n isFilterTarget(event) {\n if (!this.keyFilter) {\n return false;\n }\n const filteres = this.keyFilter.split(\"+\");\n const modifiers = [\"meta\", \"ctrl\", \"alt\", \"shift\"];\n const [meta, ctrl, alt, shift] = modifiers.map((modifier) => filteres.includes(modifier));\n if (event.metaKey !== meta || event.ctrlKey !== ctrl || event.altKey !== alt || event.shiftKey !== shift) {\n return true;\n }\n const standardFilter = filteres.filter((key) => !modifiers.includes(key))[0];\n if (!standardFilter) {\n return false;\n }\n if (!Object.prototype.hasOwnProperty.call(this.keyMappings, standardFilter)) {\n error(`contains unknown key filter: ${this.keyFilter}`);\n }\n return this.keyMappings[standardFilter].toLowerCase() !== event.key.toLowerCase();\n }\n get params() {\n const params = {};\n const pattern = new RegExp(`^data-${this.identifier}-(.+)-param$`, \"i\");\n for (const { name, value } of Array.from(this.element.attributes)) {\n const match = name.match(pattern);\n const key = match && match[1];\n if (key) {\n params[camelize(key)] = typecast(value);\n }\n }\n return params;\n }\n get eventTargetName() {\n return stringifyEventTarget(this.eventTarget);\n }\n get keyMappings() {\n return this.schema.keyMappings;\n }\n}\nconst defaultEventNames = {\n a: () => \"click\",\n button: () => \"click\",\n form: () => \"submit\",\n details: () => \"toggle\",\n input: (e) => (e.getAttribute(\"type\") == \"submit\" ? \"click\" : \"input\"),\n select: () => \"change\",\n textarea: () => \"input\",\n};\nfunction getDefaultEventNameForElement(element) {\n const tagName = element.tagName.toLowerCase();\n if (tagName in defaultEventNames) {\n return defaultEventNames[tagName](element);\n }\n}\nfunction error(message) {\n throw new Error(message);\n}\nfunction typecast(value) {\n try {\n return JSON.parse(value);\n }\n catch (o_O) {\n return value;\n }\n}\n\nclass Binding {\n constructor(context, action) {\n this.context = context;\n this.action = action;\n }\n get index() {\n return this.action.index;\n }\n get eventTarget() {\n return this.action.eventTarget;\n }\n get eventOptions() {\n return this.action.eventOptions;\n }\n get identifier() {\n return this.context.identifier;\n }\n handleEvent(event) {\n if (this.willBeInvokedByEvent(event) && this.applyEventModifiers(event)) {\n this.invokeWithEvent(event);\n }\n }\n get eventName() {\n return this.action.eventName;\n }\n get method() {\n const method = this.controller[this.methodName];\n if (typeof method == \"function\") {\n return method;\n }\n throw new Error(`Action \"${this.action}\" references undefined method \"${this.methodName}\"`);\n }\n applyEventModifiers(event) {\n const { element } = this.action;\n const { actionDescriptorFilters } = this.context.application;\n let passes = true;\n for (const [name, value] of Object.entries(this.eventOptions)) {\n if (name in actionDescriptorFilters) {\n const filter = actionDescriptorFilters[name];\n passes = passes && filter({ name, value, event, element });\n }\n else {\n continue;\n }\n }\n return passes;\n }\n invokeWithEvent(event) {\n const { target, currentTarget } = event;\n try {\n const { params } = this.action;\n const actionEvent = Object.assign(event, { params });\n this.method.call(this.controller, actionEvent);\n this.context.logDebugActivity(this.methodName, { event, target, currentTarget, action: this.methodName });\n }\n catch (error) {\n const { identifier, controller, element, index } = this;\n const detail = { identifier, controller, element, index, event };\n this.context.handleError(error, `invoking action \"${this.action}\"`, detail);\n }\n }\n willBeInvokedByEvent(event) {\n const eventTarget = event.target;\n if (event instanceof KeyboardEvent && this.action.isFilterTarget(event)) {\n return false;\n }\n if (this.element === eventTarget) {\n return true;\n }\n else if (eventTarget instanceof Element && this.element.contains(eventTarget)) {\n return this.scope.containsElement(eventTarget);\n }\n else {\n return this.scope.containsElement(this.action.element);\n }\n }\n get controller() {\n return this.context.controller;\n }\n get methodName() {\n return this.action.methodName;\n }\n get element() {\n return this.scope.element;\n }\n get scope() {\n return this.context.scope;\n }\n}\n\nclass ElementObserver {\n constructor(element, delegate) {\n this.mutationObserverInit = { attributes: true, childList: true, subtree: true };\n this.element = element;\n this.started = false;\n this.delegate = delegate;\n this.elements = new Set();\n this.mutationObserver = new MutationObserver((mutations) => this.processMutations(mutations));\n }\n start() {\n if (!this.started) {\n this.started = true;\n this.mutationObserver.observe(this.element, this.mutationObserverInit);\n this.refresh();\n }\n }\n pause(callback) {\n if (this.started) {\n this.mutationObserver.disconnect();\n this.started = false;\n }\n callback();\n if (!this.started) {\n this.mutationObserver.observe(this.element, this.mutationObserverInit);\n this.started = true;\n }\n }\n stop() {\n if (this.started) {\n this.mutationObserver.takeRecords();\n this.mutationObserver.disconnect();\n this.started = false;\n }\n }\n refresh() {\n if (this.started) {\n const matches = new Set(this.matchElementsInTree());\n for (const element of Array.from(this.elements)) {\n if (!matches.has(element)) {\n this.removeElement(element);\n }\n }\n for (const element of Array.from(matches)) {\n this.addElement(element);\n }\n }\n }\n processMutations(mutations) {\n if (this.started) {\n for (const mutation of mutations) {\n this.processMutation(mutation);\n }\n }\n }\n processMutation(mutation) {\n if (mutation.type == \"attributes\") {\n this.processAttributeChange(mutation.target, mutation.attributeName);\n }\n else if (mutation.type == \"childList\") {\n this.processRemovedNodes(mutation.removedNodes);\n this.processAddedNodes(mutation.addedNodes);\n }\n }\n processAttributeChange(node, attributeName) {\n const element = node;\n if (this.elements.has(element)) {\n if (this.delegate.elementAttributeChanged && this.matchElement(element)) {\n this.delegate.elementAttributeChanged(element, attributeName);\n }\n else {\n this.removeElement(element);\n }\n }\n else if (this.matchElement(element)) {\n this.addElement(element);\n }\n }\n processRemovedNodes(nodes) {\n for (const node of Array.from(nodes)) {\n const element = this.elementFromNode(node);\n if (element) {\n this.processTree(element, this.removeElement);\n }\n }\n }\n processAddedNodes(nodes) {\n for (const node of Array.from(nodes)) {\n const element = this.elementFromNode(node);\n if (element && this.elementIsActive(element)) {\n this.processTree(element, this.addElement);\n }\n }\n }\n matchElement(element) {\n return this.delegate.matchElement(element);\n }\n matchElementsInTree(tree = this.element) {\n return this.delegate.matchElementsInTree(tree);\n }\n processTree(tree, processor) {\n for (const element of this.matchElementsInTree(tree)) {\n processor.call(this, element);\n }\n }\n elementFromNode(node) {\n if (node.nodeType == Node.ELEMENT_NODE) {\n return node;\n }\n }\n elementIsActive(element) {\n if (element.isConnected != this.element.isConnected) {\n return false;\n }\n else {\n return this.element.contains(element);\n }\n }\n addElement(element) {\n if (!this.elements.has(element)) {\n if (this.elementIsActive(element)) {\n this.elements.add(element);\n if (this.delegate.elementMatched) {\n this.delegate.elementMatched(element);\n }\n }\n }\n }\n removeElement(element) {\n if (this.elements.has(element)) {\n this.elements.delete(element);\n if (this.delegate.elementUnmatched) {\n this.delegate.elementUnmatched(element);\n }\n }\n }\n}\n\nclass AttributeObserver {\n constructor(element, attributeName, delegate) {\n this.attributeName = attributeName;\n this.delegate = delegate;\n this.elementObserver = new ElementObserver(element, this);\n }\n get element() {\n return this.elementObserver.element;\n }\n get selector() {\n return `[${this.attributeName}]`;\n }\n start() {\n this.elementObserver.start();\n }\n pause(callback) {\n this.elementObserver.pause(callback);\n }\n stop() {\n this.elementObserver.stop();\n }\n refresh() {\n this.elementObserver.refresh();\n }\n get started() {\n return this.elementObserver.started;\n }\n matchElement(element) {\n return element.hasAttribute(this.attributeName);\n }\n matchElementsInTree(tree) {\n const match = this.matchElement(tree) ? [tree] : [];\n const matches = Array.from(tree.querySelectorAll(this.selector));\n return match.concat(matches);\n }\n elementMatched(element) {\n if (this.delegate.elementMatchedAttribute) {\n this.delegate.elementMatchedAttribute(element, this.attributeName);\n }\n }\n elementUnmatched(element) {\n if (this.delegate.elementUnmatchedAttribute) {\n this.delegate.elementUnmatchedAttribute(element, this.attributeName);\n }\n }\n elementAttributeChanged(element, attributeName) {\n if (this.delegate.elementAttributeValueChanged && this.attributeName == attributeName) {\n this.delegate.elementAttributeValueChanged(element, attributeName);\n }\n }\n}\n\nfunction add(map, key, value) {\n fetch(map, key).add(value);\n}\nfunction del(map, key, value) {\n fetch(map, key).delete(value);\n prune(map, key);\n}\nfunction fetch(map, key) {\n let values = map.get(key);\n if (!values) {\n values = new Set();\n map.set(key, values);\n }\n return values;\n}\nfunction prune(map, key) {\n const values = map.get(key);\n if (values != null && values.size == 0) {\n map.delete(key);\n }\n}\n\nclass Multimap {\n constructor() {\n this.valuesByKey = new Map();\n }\n get keys() {\n return Array.from(this.valuesByKey.keys());\n }\n get values() {\n const sets = Array.from(this.valuesByKey.values());\n return sets.reduce((values, set) => values.concat(Array.from(set)), []);\n }\n get size() {\n const sets = Array.from(this.valuesByKey.values());\n return sets.reduce((size, set) => size + set.size, 0);\n }\n add(key, value) {\n add(this.valuesByKey, key, value);\n }\n delete(key, value) {\n del(this.valuesByKey, key, value);\n }\n has(key, value) {\n const values = this.valuesByKey.get(key);\n return values != null && values.has(value);\n }\n hasKey(key) {\n return this.valuesByKey.has(key);\n }\n hasValue(value) {\n const sets = Array.from(this.valuesByKey.values());\n return sets.some((set) => set.has(value));\n }\n getValuesForKey(key) {\n const values = this.valuesByKey.get(key);\n return values ? Array.from(values) : [];\n }\n getKeysForValue(value) {\n return Array.from(this.valuesByKey)\n .filter(([_key, values]) => values.has(value))\n .map(([key, _values]) => key);\n }\n}\n\nclass IndexedMultimap extends Multimap {\n constructor() {\n super();\n this.keysByValue = new Map();\n }\n get values() {\n return Array.from(this.keysByValue.keys());\n }\n add(key, value) {\n super.add(key, value);\n add(this.keysByValue, value, key);\n }\n delete(key, value) {\n super.delete(key, value);\n del(this.keysByValue, value, key);\n }\n hasValue(value) {\n return this.keysByValue.has(value);\n }\n getKeysForValue(value) {\n const set = this.keysByValue.get(value);\n return set ? Array.from(set) : [];\n }\n}\n\nclass SelectorObserver {\n constructor(element, selector, delegate, details = {}) {\n this.selector = selector;\n this.details = details;\n this.elementObserver = new ElementObserver(element, this);\n this.delegate = delegate;\n this.matchesByElement = new Multimap();\n }\n get started() {\n return this.elementObserver.started;\n }\n start() {\n this.elementObserver.start();\n }\n pause(callback) {\n this.elementObserver.pause(callback);\n }\n stop() {\n this.elementObserver.stop();\n }\n refresh() {\n this.elementObserver.refresh();\n }\n get element() {\n return this.elementObserver.element;\n }\n matchElement(element) {\n const matches = element.matches(this.selector);\n if (this.delegate.selectorMatchElement) {\n return matches && this.delegate.selectorMatchElement(element, this.details);\n }\n return matches;\n }\n matchElementsInTree(tree) {\n const match = this.matchElement(tree) ? [tree] : [];\n const matches = Array.from(tree.querySelectorAll(this.selector)).filter((match) => this.matchElement(match));\n return match.concat(matches);\n }\n elementMatched(element) {\n this.selectorMatched(element);\n }\n elementUnmatched(element) {\n this.selectorUnmatched(element);\n }\n elementAttributeChanged(element, _attributeName) {\n const matches = this.matchElement(element);\n const matchedBefore = this.matchesByElement.has(this.selector, element);\n if (!matches && matchedBefore) {\n this.selectorUnmatched(element);\n }\n }\n selectorMatched(element) {\n if (this.delegate.selectorMatched) {\n this.delegate.selectorMatched(element, this.selector, this.details);\n this.matchesByElement.add(this.selector, element);\n }\n }\n selectorUnmatched(element) {\n this.delegate.selectorUnmatched(element, this.selector, this.details);\n this.matchesByElement.delete(this.selector, element);\n }\n}\n\nclass StringMapObserver {\n constructor(element, delegate) {\n this.element = element;\n this.delegate = delegate;\n this.started = false;\n this.stringMap = new Map();\n this.mutationObserver = new MutationObserver((mutations) => this.processMutations(mutations));\n }\n start() {\n if (!this.started) {\n this.started = true;\n this.mutationObserver.observe(this.element, { attributes: true, attributeOldValue: true });\n this.refresh();\n }\n }\n stop() {\n if (this.started) {\n this.mutationObserver.takeRecords();\n this.mutationObserver.disconnect();\n this.started = false;\n }\n }\n refresh() {\n if (this.started) {\n for (const attributeName of this.knownAttributeNames) {\n this.refreshAttribute(attributeName, null);\n }\n }\n }\n processMutations(mutations) {\n if (this.started) {\n for (const mutation of mutations) {\n this.processMutation(mutation);\n }\n }\n }\n processMutation(mutation) {\n const attributeName = mutation.attributeName;\n if (attributeName) {\n this.refreshAttribute(attributeName, mutation.oldValue);\n }\n }\n refreshAttribute(attributeName, oldValue) {\n const key = this.delegate.getStringMapKeyForAttribute(attributeName);\n if (key != null) {\n if (!this.stringMap.has(attributeName)) {\n this.stringMapKeyAdded(key, attributeName);\n }\n const value = this.element.getAttribute(attributeName);\n if (this.stringMap.get(attributeName) != value) {\n this.stringMapValueChanged(value, key, oldValue);\n }\n if (value == null) {\n const oldValue = this.stringMap.get(attributeName);\n this.stringMap.delete(attributeName);\n if (oldValue)\n this.stringMapKeyRemoved(key, attributeName, oldValue);\n }\n else {\n this.stringMap.set(attributeName, value);\n }\n }\n }\n stringMapKeyAdded(key, attributeName) {\n if (this.delegate.stringMapKeyAdded) {\n this.delegate.stringMapKeyAdded(key, attributeName);\n }\n }\n stringMapValueChanged(value, key, oldValue) {\n if (this.delegate.stringMapValueChanged) {\n this.delegate.stringMapValueChanged(value, key, oldValue);\n }\n }\n stringMapKeyRemoved(key, attributeName, oldValue) {\n if (this.delegate.stringMapKeyRemoved) {\n this.delegate.stringMapKeyRemoved(key, attributeName, oldValue);\n }\n }\n get knownAttributeNames() {\n return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)));\n }\n get currentAttributeNames() {\n return Array.from(this.element.attributes).map((attribute) => attribute.name);\n }\n get recordedAttributeNames() {\n return Array.from(this.stringMap.keys());\n }\n}\n\nclass TokenListObserver {\n constructor(element, attributeName, delegate) {\n this.attributeObserver = new AttributeObserver(element, attributeName, this);\n this.delegate = delegate;\n this.tokensByElement = new Multimap();\n }\n get started() {\n return this.attributeObserver.started;\n }\n start() {\n this.attributeObserver.start();\n }\n pause(callback) {\n this.attributeObserver.pause(callback);\n }\n stop() {\n this.attributeObserver.stop();\n }\n refresh() {\n this.attributeObserver.refresh();\n }\n get element() {\n return this.attributeObserver.element;\n }\n get attributeName() {\n return this.attributeObserver.attributeName;\n }\n elementMatchedAttribute(element) {\n this.tokensMatched(this.readTokensForElement(element));\n }\n elementAttributeValueChanged(element) {\n const [unmatchedTokens, matchedTokens] = this.refreshTokensForElement(element);\n this.tokensUnmatched(unmatchedTokens);\n this.tokensMatched(matchedTokens);\n }\n elementUnmatchedAttribute(element) {\n this.tokensUnmatched(this.tokensByElement.getValuesForKey(element));\n }\n tokensMatched(tokens) {\n tokens.forEach((token) => this.tokenMatched(token));\n }\n tokensUnmatched(tokens) {\n tokens.forEach((token) => this.tokenUnmatched(token));\n }\n tokenMatched(token) {\n this.delegate.tokenMatched(token);\n this.tokensByElement.add(token.element, token);\n }\n tokenUnmatched(token) {\n this.delegate.tokenUnmatched(token);\n this.tokensByElement.delete(token.element, token);\n }\n refreshTokensForElement(element) {\n const previousTokens = this.tokensByElement.getValuesForKey(element);\n const currentTokens = this.readTokensForElement(element);\n const firstDifferingIndex = zip(previousTokens, currentTokens).findIndex(([previousToken, currentToken]) => !tokensAreEqual(previousToken, currentToken));\n if (firstDifferingIndex == -1) {\n return [[], []];\n }\n else {\n return [previousTokens.slice(firstDifferingIndex), currentTokens.slice(firstDifferingIndex)];\n }\n }\n readTokensForElement(element) {\n const attributeName = this.attributeName;\n const tokenString = element.getAttribute(attributeName) || \"\";\n return parseTokenString(tokenString, element, attributeName);\n }\n}\nfunction parseTokenString(tokenString, element, attributeName) {\n return tokenString\n .trim()\n .split(/\\s+/)\n .filter((content) => content.length)\n .map((content, index) => ({ element, attributeName, content, index }));\n}\nfunction zip(left, right) {\n const length = Math.max(left.length, right.length);\n return Array.from({ length }, (_, index) => [left[index], right[index]]);\n}\nfunction tokensAreEqual(left, right) {\n return left && right && left.index == right.index && left.content == right.content;\n}\n\nclass ValueListObserver {\n constructor(element, attributeName, delegate) {\n this.tokenListObserver = new TokenListObserver(element, attributeName, this);\n this.delegate = delegate;\n this.parseResultsByToken = new WeakMap();\n this.valuesByTokenByElement = new WeakMap();\n }\n get started() {\n return this.tokenListObserver.started;\n }\n start() {\n this.tokenListObserver.start();\n }\n stop() {\n this.tokenListObserver.stop();\n }\n refresh() {\n this.tokenListObserver.refresh();\n }\n get element() {\n return this.tokenListObserver.element;\n }\n get attributeName() {\n return this.tokenListObserver.attributeName;\n }\n tokenMatched(token) {\n const { element } = token;\n const { value } = this.fetchParseResultForToken(token);\n if (value) {\n this.fetchValuesByTokenForElement(element).set(token, value);\n this.delegate.elementMatchedValue(element, value);\n }\n }\n tokenUnmatched(token) {\n const { element } = token;\n const { value } = this.fetchParseResultForToken(token);\n if (value) {\n this.fetchValuesByTokenForElement(element).delete(token);\n this.delegate.elementUnmatchedValue(element, value);\n }\n }\n fetchParseResultForToken(token) {\n let parseResult = this.parseResultsByToken.get(token);\n if (!parseResult) {\n parseResult = this.parseToken(token);\n this.parseResultsByToken.set(token, parseResult);\n }\n return parseResult;\n }\n fetchValuesByTokenForElement(element) {\n let valuesByToken = this.valuesByTokenByElement.get(element);\n if (!valuesByToken) {\n valuesByToken = new Map();\n this.valuesByTokenByElement.set(element, valuesByToken);\n }\n return valuesByToken;\n }\n parseToken(token) {\n try {\n const value = this.delegate.parseValueForToken(token);\n return { value };\n }\n catch (error) {\n return { error };\n }\n }\n}\n\nclass BindingObserver {\n constructor(context, delegate) {\n this.context = context;\n this.delegate = delegate;\n this.bindingsByAction = new Map();\n }\n start() {\n if (!this.valueListObserver) {\n this.valueListObserver = new ValueListObserver(this.element, this.actionAttribute, this);\n this.valueListObserver.start();\n }\n }\n stop() {\n if (this.valueListObserver) {\n this.valueListObserver.stop();\n delete this.valueListObserver;\n this.disconnectAllActions();\n }\n }\n get element() {\n return this.context.element;\n }\n get identifier() {\n return this.context.identifier;\n }\n get actionAttribute() {\n return this.schema.actionAttribute;\n }\n get schema() {\n return this.context.schema;\n }\n get bindings() {\n return Array.from(this.bindingsByAction.values());\n }\n connectAction(action) {\n const binding = new Binding(this.context, action);\n this.bindingsByAction.set(action, binding);\n this.delegate.bindingConnected(binding);\n }\n disconnectAction(action) {\n const binding = this.bindingsByAction.get(action);\n if (binding) {\n this.bindingsByAction.delete(action);\n this.delegate.bindingDisconnected(binding);\n }\n }\n disconnectAllActions() {\n this.bindings.forEach((binding) => this.delegate.bindingDisconnected(binding, true));\n this.bindingsByAction.clear();\n }\n parseValueForToken(token) {\n const action = Action.forToken(token, this.schema);\n if (action.identifier == this.identifier) {\n return action;\n }\n }\n elementMatchedValue(element, action) {\n this.connectAction(action);\n }\n elementUnmatchedValue(element, action) {\n this.disconnectAction(action);\n }\n}\n\nclass ValueObserver {\n constructor(context, receiver) {\n this.context = context;\n this.receiver = receiver;\n this.stringMapObserver = new StringMapObserver(this.element, this);\n this.valueDescriptorMap = this.controller.valueDescriptorMap;\n }\n start() {\n this.stringMapObserver.start();\n this.invokeChangedCallbacksForDefaultValues();\n }\n stop() {\n this.stringMapObserver.stop();\n }\n get element() {\n return this.context.element;\n }\n get controller() {\n return this.context.controller;\n }\n getStringMapKeyForAttribute(attributeName) {\n if (attributeName in this.valueDescriptorMap) {\n return this.valueDescriptorMap[attributeName].name;\n }\n }\n stringMapKeyAdded(key, attributeName) {\n const descriptor = this.valueDescriptorMap[attributeName];\n if (!this.hasValue(key)) {\n this.invokeChangedCallback(key, descriptor.writer(this.receiver[key]), descriptor.writer(descriptor.defaultValue));\n }\n }\n stringMapValueChanged(value, name, oldValue) {\n const descriptor = this.valueDescriptorNameMap[name];\n if (value === null)\n return;\n if (oldValue === null) {\n oldValue = descriptor.writer(descriptor.defaultValue);\n }\n this.invokeChangedCallback(name, value, oldValue);\n }\n stringMapKeyRemoved(key, attributeName, oldValue) {\n const descriptor = this.valueDescriptorNameMap[key];\n if (this.hasValue(key)) {\n this.invokeChangedCallback(key, descriptor.writer(this.receiver[key]), oldValue);\n }\n else {\n this.invokeChangedCallback(key, descriptor.writer(descriptor.defaultValue), oldValue);\n }\n }\n invokeChangedCallbacksForDefaultValues() {\n for (const { key, name, defaultValue, writer } of this.valueDescriptors) {\n if (defaultValue != undefined && !this.controller.data.has(key)) {\n this.invokeChangedCallback(name, writer(defaultValue), undefined);\n }\n }\n }\n invokeChangedCallback(name, rawValue, rawOldValue) {\n const changedMethodName = `${name}Changed`;\n const changedMethod = this.receiver[changedMethodName];\n if (typeof changedMethod == \"function\") {\n const descriptor = this.valueDescriptorNameMap[name];\n try {\n const value = descriptor.reader(rawValue);\n let oldValue = rawOldValue;\n if (rawOldValue) {\n oldValue = descriptor.reader(rawOldValue);\n }\n changedMethod.call(this.receiver, value, oldValue);\n }\n catch (error) {\n if (error instanceof TypeError) {\n error.message = `Stimulus Value \"${this.context.identifier}.${descriptor.name}\" - ${error.message}`;\n }\n throw error;\n }\n }\n }\n get valueDescriptors() {\n const { valueDescriptorMap } = this;\n return Object.keys(valueDescriptorMap).map((key) => valueDescriptorMap[key]);\n }\n get valueDescriptorNameMap() {\n const descriptors = {};\n Object.keys(this.valueDescriptorMap).forEach((key) => {\n const descriptor = this.valueDescriptorMap[key];\n descriptors[descriptor.name] = descriptor;\n });\n return descriptors;\n }\n hasValue(attributeName) {\n const descriptor = this.valueDescriptorNameMap[attributeName];\n const hasMethodName = `has${capitalize(descriptor.name)}`;\n return this.receiver[hasMethodName];\n }\n}\n\nclass TargetObserver {\n constructor(context, delegate) {\n this.context = context;\n this.delegate = delegate;\n this.targetsByName = new Multimap();\n }\n start() {\n if (!this.tokenListObserver) {\n this.tokenListObserver = new TokenListObserver(this.element, this.attributeName, this);\n this.tokenListObserver.start();\n }\n }\n stop() {\n if (this.tokenListObserver) {\n this.disconnectAllTargets();\n this.tokenListObserver.stop();\n delete this.tokenListObserver;\n }\n }\n tokenMatched({ element, content: name }) {\n if (this.scope.containsElement(element)) {\n this.connectTarget(element, name);\n }\n }\n tokenUnmatched({ element, content: name }) {\n this.disconnectTarget(element, name);\n }\n connectTarget(element, name) {\n var _a;\n if (!this.targetsByName.has(name, element)) {\n this.targetsByName.add(name, element);\n (_a = this.tokenListObserver) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.targetConnected(element, name));\n }\n }\n disconnectTarget(element, name) {\n var _a;\n if (this.targetsByName.has(name, element)) {\n this.targetsByName.delete(name, element);\n (_a = this.tokenListObserver) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.targetDisconnected(element, name));\n }\n }\n disconnectAllTargets() {\n for (const name of this.targetsByName.keys) {\n for (const element of this.targetsByName.getValuesForKey(name)) {\n this.disconnectTarget(element, name);\n }\n }\n }\n get attributeName() {\n return `data-${this.context.identifier}-target`;\n }\n get element() {\n return this.context.element;\n }\n get scope() {\n return this.context.scope;\n }\n}\n\nfunction readInheritableStaticArrayValues(constructor, propertyName) {\n const ancestors = getAncestorsForConstructor(constructor);\n return Array.from(ancestors.reduce((values, constructor) => {\n getOwnStaticArrayValues(constructor, propertyName).forEach((name) => values.add(name));\n return values;\n }, new Set()));\n}\nfunction readInheritableStaticObjectPairs(constructor, propertyName) {\n const ancestors = getAncestorsForConstructor(constructor);\n return ancestors.reduce((pairs, constructor) => {\n pairs.push(...getOwnStaticObjectPairs(constructor, propertyName));\n return pairs;\n }, []);\n}\nfunction getAncestorsForConstructor(constructor) {\n const ancestors = [];\n while (constructor) {\n ancestors.push(constructor);\n constructor = Object.getPrototypeOf(constructor);\n }\n return ancestors.reverse();\n}\nfunction getOwnStaticArrayValues(constructor, propertyName) {\n const definition = constructor[propertyName];\n return Array.isArray(definition) ? definition : [];\n}\nfunction getOwnStaticObjectPairs(constructor, propertyName) {\n const definition = constructor[propertyName];\n return definition ? Object.keys(definition).map((key) => [key, definition[key]]) : [];\n}\n\nclass OutletObserver {\n constructor(context, delegate) {\n this.context = context;\n this.delegate = delegate;\n this.outletsByName = new Multimap();\n this.outletElementsByName = new Multimap();\n this.selectorObserverMap = new Map();\n }\n start() {\n if (this.selectorObserverMap.size === 0) {\n this.outletDefinitions.forEach((outletName) => {\n const selector = this.selector(outletName);\n const details = { outletName };\n if (selector) {\n this.selectorObserverMap.set(outletName, new SelectorObserver(document.body, selector, this, details));\n }\n });\n this.selectorObserverMap.forEach((observer) => observer.start());\n }\n this.dependentContexts.forEach((context) => context.refresh());\n }\n stop() {\n if (this.selectorObserverMap.size > 0) {\n this.disconnectAllOutlets();\n this.selectorObserverMap.forEach((observer) => observer.stop());\n this.selectorObserverMap.clear();\n }\n }\n refresh() {\n this.selectorObserverMap.forEach((observer) => observer.refresh());\n }\n selectorMatched(element, _selector, { outletName }) {\n const outlet = this.getOutlet(element, outletName);\n if (outlet) {\n this.connectOutlet(outlet, element, outletName);\n }\n }\n selectorUnmatched(element, _selector, { outletName }) {\n const outlet = this.getOutletFromMap(element, outletName);\n if (outlet) {\n this.disconnectOutlet(outlet, element, outletName);\n }\n }\n selectorMatchElement(element, { outletName }) {\n return (this.hasOutlet(element, outletName) &&\n element.matches(`[${this.context.application.schema.controllerAttribute}~=${outletName}]`));\n }\n connectOutlet(outlet, element, outletName) {\n var _a;\n if (!this.outletElementsByName.has(outletName, element)) {\n this.outletsByName.add(outletName, outlet);\n this.outletElementsByName.add(outletName, element);\n (_a = this.selectorObserverMap.get(outletName)) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.outletConnected(outlet, element, outletName));\n }\n }\n disconnectOutlet(outlet, element, outletName) {\n var _a;\n if (this.outletElementsByName.has(outletName, element)) {\n this.outletsByName.delete(outletName, outlet);\n this.outletElementsByName.delete(outletName, element);\n (_a = this.selectorObserverMap\n .get(outletName)) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.outletDisconnected(outlet, element, outletName));\n }\n }\n disconnectAllOutlets() {\n for (const outletName of this.outletElementsByName.keys) {\n for (const element of this.outletElementsByName.getValuesForKey(outletName)) {\n for (const outlet of this.outletsByName.getValuesForKey(outletName)) {\n this.disconnectOutlet(outlet, element, outletName);\n }\n }\n }\n }\n selector(outletName) {\n return this.scope.outlets.getSelectorForOutletName(outletName);\n }\n get outletDependencies() {\n const dependencies = new Multimap();\n this.router.modules.forEach((module) => {\n const constructor = module.definition.controllerConstructor;\n const outlets = readInheritableStaticArrayValues(constructor, \"outlets\");\n outlets.forEach((outlet) => dependencies.add(outlet, module.identifier));\n });\n return dependencies;\n }\n get outletDefinitions() {\n return this.outletDependencies.getKeysForValue(this.identifier);\n }\n get dependentControllerIdentifiers() {\n return this.outletDependencies.getValuesForKey(this.identifier);\n }\n get dependentContexts() {\n const identifiers = this.dependentControllerIdentifiers;\n return this.router.contexts.filter((context) => identifiers.includes(context.identifier));\n }\n hasOutlet(element, outletName) {\n return !!this.getOutlet(element, outletName) || !!this.getOutletFromMap(element, outletName);\n }\n getOutlet(element, outletName) {\n return this.application.getControllerForElementAndIdentifier(element, outletName);\n }\n getOutletFromMap(element, outletName) {\n return this.outletsByName.getValuesForKey(outletName).find((outlet) => outlet.element === element);\n }\n get scope() {\n return this.context.scope;\n }\n get identifier() {\n return this.context.identifier;\n }\n get application() {\n return this.context.application;\n }\n get router() {\n return this.application.router;\n }\n}\n\nclass Context {\n constructor(module, scope) {\n this.logDebugActivity = (functionName, detail = {}) => {\n const { identifier, controller, element } = this;\n detail = Object.assign({ identifier, controller, element }, detail);\n this.application.logDebugActivity(this.identifier, functionName, detail);\n };\n this.module = module;\n this.scope = scope;\n this.controller = new module.controllerConstructor(this);\n this.bindingObserver = new BindingObserver(this, this.dispatcher);\n this.valueObserver = new ValueObserver(this, this.controller);\n this.targetObserver = new TargetObserver(this, this);\n this.outletObserver = new OutletObserver(this, this);\n try {\n this.controller.initialize();\n this.logDebugActivity(\"initialize\");\n }\n catch (error) {\n this.handleError(error, \"initializing controller\");\n }\n }\n connect() {\n this.bindingObserver.start();\n this.valueObserver.start();\n this.targetObserver.start();\n this.outletObserver.start();\n try {\n this.controller.connect();\n this.logDebugActivity(\"connect\");\n }\n catch (error) {\n this.handleError(error, \"connecting controller\");\n }\n }\n refresh() {\n this.outletObserver.refresh();\n }\n disconnect() {\n try {\n this.controller.disconnect();\n this.logDebugActivity(\"disconnect\");\n }\n catch (error) {\n this.handleError(error, \"disconnecting controller\");\n }\n this.outletObserver.stop();\n this.targetObserver.stop();\n this.valueObserver.stop();\n this.bindingObserver.stop();\n }\n get application() {\n return this.module.application;\n }\n get identifier() {\n return this.module.identifier;\n }\n get schema() {\n return this.application.schema;\n }\n get dispatcher() {\n return this.application.dispatcher;\n }\n get element() {\n return this.scope.element;\n }\n get parentElement() {\n return this.element.parentElement;\n }\n handleError(error, message, detail = {}) {\n const { identifier, controller, element } = this;\n detail = Object.assign({ identifier, controller, element }, detail);\n this.application.handleError(error, `Error ${message}`, detail);\n }\n targetConnected(element, name) {\n this.invokeControllerMethod(`${name}TargetConnected`, element);\n }\n targetDisconnected(element, name) {\n this.invokeControllerMethod(`${name}TargetDisconnected`, element);\n }\n outletConnected(outlet, element, name) {\n this.invokeControllerMethod(`${namespaceCamelize(name)}OutletConnected`, outlet, element);\n }\n outletDisconnected(outlet, element, name) {\n this.invokeControllerMethod(`${namespaceCamelize(name)}OutletDisconnected`, outlet, element);\n }\n invokeControllerMethod(methodName, ...args) {\n const controller = this.controller;\n if (typeof controller[methodName] == \"function\") {\n controller[methodName](...args);\n }\n }\n}\n\nfunction bless(constructor) {\n return shadow(constructor, getBlessedProperties(constructor));\n}\nfunction shadow(constructor, properties) {\n const shadowConstructor = extend(constructor);\n const shadowProperties = getShadowProperties(constructor.prototype, properties);\n Object.defineProperties(shadowConstructor.prototype, shadowProperties);\n return shadowConstructor;\n}\nfunction getBlessedProperties(constructor) {\n const blessings = readInheritableStaticArrayValues(constructor, \"blessings\");\n return blessings.reduce((blessedProperties, blessing) => {\n const properties = blessing(constructor);\n for (const key in properties) {\n const descriptor = blessedProperties[key] || {};\n blessedProperties[key] = Object.assign(descriptor, properties[key]);\n }\n return blessedProperties;\n }, {});\n}\nfunction getShadowProperties(prototype, properties) {\n return getOwnKeys(properties).reduce((shadowProperties, key) => {\n const descriptor = getShadowedDescriptor(prototype, properties, key);\n if (descriptor) {\n Object.assign(shadowProperties, { [key]: descriptor });\n }\n return shadowProperties;\n }, {});\n}\nfunction getShadowedDescriptor(prototype, properties, key) {\n const shadowingDescriptor = Object.getOwnPropertyDescriptor(prototype, key);\n const shadowedByValue = shadowingDescriptor && \"value\" in shadowingDescriptor;\n if (!shadowedByValue) {\n const descriptor = Object.getOwnPropertyDescriptor(properties, key).value;\n if (shadowingDescriptor) {\n descriptor.get = shadowingDescriptor.get || descriptor.get;\n descriptor.set = shadowingDescriptor.set || descriptor.set;\n }\n return descriptor;\n }\n}\nconst getOwnKeys = (() => {\n if (typeof Object.getOwnPropertySymbols == \"function\") {\n return (object) => [...Object.getOwnPropertyNames(object), ...Object.getOwnPropertySymbols(object)];\n }\n else {\n return Object.getOwnPropertyNames;\n }\n})();\nconst extend = (() => {\n function extendWithReflect(constructor) {\n function extended() {\n return Reflect.construct(constructor, arguments, new.target);\n }\n extended.prototype = Object.create(constructor.prototype, {\n constructor: { value: extended },\n });\n Reflect.setPrototypeOf(extended, constructor);\n return extended;\n }\n function testReflectExtension() {\n const a = function () {\n this.a.call(this);\n };\n const b = extendWithReflect(a);\n b.prototype.a = function () { };\n return new b();\n }\n try {\n testReflectExtension();\n return extendWithReflect;\n }\n catch (error) {\n return (constructor) => class extended extends constructor {\n };\n }\n})();\n\nfunction blessDefinition(definition) {\n return {\n identifier: definition.identifier,\n controllerConstructor: bless(definition.controllerConstructor),\n };\n}\n\nclass Module {\n constructor(application, definition) {\n this.application = application;\n this.definition = blessDefinition(definition);\n this.contextsByScope = new WeakMap();\n this.connectedContexts = new Set();\n }\n get identifier() {\n return this.definition.identifier;\n }\n get controllerConstructor() {\n return this.definition.controllerConstructor;\n }\n get contexts() {\n return Array.from(this.connectedContexts);\n }\n connectContextForScope(scope) {\n const context = this.fetchContextForScope(scope);\n this.connectedContexts.add(context);\n context.connect();\n }\n disconnectContextForScope(scope) {\n const context = this.contextsByScope.get(scope);\n if (context) {\n this.connectedContexts.delete(context);\n context.disconnect();\n }\n }\n fetchContextForScope(scope) {\n let context = this.contextsByScope.get(scope);\n if (!context) {\n context = new Context(this, scope);\n this.contextsByScope.set(scope, context);\n }\n return context;\n }\n}\n\nclass ClassMap {\n constructor(scope) {\n this.scope = scope;\n }\n has(name) {\n return this.data.has(this.getDataKey(name));\n }\n get(name) {\n return this.getAll(name)[0];\n }\n getAll(name) {\n const tokenString = this.data.get(this.getDataKey(name)) || \"\";\n return tokenize(tokenString);\n }\n getAttributeName(name) {\n return this.data.getAttributeNameForKey(this.getDataKey(name));\n }\n getDataKey(name) {\n return `${name}-class`;\n }\n get data() {\n return this.scope.data;\n }\n}\n\nclass DataMap {\n constructor(scope) {\n this.scope = scope;\n }\n get element() {\n return this.scope.element;\n }\n get identifier() {\n return this.scope.identifier;\n }\n get(key) {\n const name = this.getAttributeNameForKey(key);\n return this.element.getAttribute(name);\n }\n set(key, value) {\n const name = this.getAttributeNameForKey(key);\n this.element.setAttribute(name, value);\n return this.get(key);\n }\n has(key) {\n const name = this.getAttributeNameForKey(key);\n return this.element.hasAttribute(name);\n }\n delete(key) {\n if (this.has(key)) {\n const name = this.getAttributeNameForKey(key);\n this.element.removeAttribute(name);\n return true;\n }\n else {\n return false;\n }\n }\n getAttributeNameForKey(key) {\n return `data-${this.identifier}-${dasherize(key)}`;\n }\n}\n\nclass Guide {\n constructor(logger) {\n this.warnedKeysByObject = new WeakMap();\n this.logger = logger;\n }\n warn(object, key, message) {\n let warnedKeys = this.warnedKeysByObject.get(object);\n if (!warnedKeys) {\n warnedKeys = new Set();\n this.warnedKeysByObject.set(object, warnedKeys);\n }\n if (!warnedKeys.has(key)) {\n warnedKeys.add(key);\n this.logger.warn(message, object);\n }\n }\n}\n\nfunction attributeValueContainsToken(attributeName, token) {\n return `[${attributeName}~=\"${token}\"]`;\n}\n\nclass TargetSet {\n constructor(scope) {\n this.scope = scope;\n }\n get element() {\n return this.scope.element;\n }\n get identifier() {\n return this.scope.identifier;\n }\n get schema() {\n return this.scope.schema;\n }\n has(targetName) {\n return this.find(targetName) != null;\n }\n find(...targetNames) {\n return targetNames.reduce((target, targetName) => target || this.findTarget(targetName) || this.findLegacyTarget(targetName), undefined);\n }\n findAll(...targetNames) {\n return targetNames.reduce((targets, targetName) => [\n ...targets,\n ...this.findAllTargets(targetName),\n ...this.findAllLegacyTargets(targetName),\n ], []);\n }\n findTarget(targetName) {\n const selector = this.getSelectorForTargetName(targetName);\n return this.scope.findElement(selector);\n }\n findAllTargets(targetName) {\n const selector = this.getSelectorForTargetName(targetName);\n return this.scope.findAllElements(selector);\n }\n getSelectorForTargetName(targetName) {\n const attributeName = this.schema.targetAttributeForScope(this.identifier);\n return attributeValueContainsToken(attributeName, targetName);\n }\n findLegacyTarget(targetName) {\n const selector = this.getLegacySelectorForTargetName(targetName);\n return this.deprecate(this.scope.findElement(selector), targetName);\n }\n findAllLegacyTargets(targetName) {\n const selector = this.getLegacySelectorForTargetName(targetName);\n return this.scope.findAllElements(selector).map((element) => this.deprecate(element, targetName));\n }\n getLegacySelectorForTargetName(targetName) {\n const targetDescriptor = `${this.identifier}.${targetName}`;\n return attributeValueContainsToken(this.schema.targetAttribute, targetDescriptor);\n }\n deprecate(element, targetName) {\n if (element) {\n const { identifier } = this;\n const attributeName = this.schema.targetAttribute;\n const revisedAttributeName = this.schema.targetAttributeForScope(identifier);\n this.guide.warn(element, `target:${targetName}`, `Please replace ${attributeName}=\"${identifier}.${targetName}\" with ${revisedAttributeName}=\"${targetName}\". ` +\n `The ${attributeName} attribute is deprecated and will be removed in a future version of Stimulus.`);\n }\n return element;\n }\n get guide() {\n return this.scope.guide;\n }\n}\n\nclass OutletSet {\n constructor(scope, controllerElement) {\n this.scope = scope;\n this.controllerElement = controllerElement;\n }\n get element() {\n return this.scope.element;\n }\n get identifier() {\n return this.scope.identifier;\n }\n get schema() {\n return this.scope.schema;\n }\n has(outletName) {\n return this.find(outletName) != null;\n }\n find(...outletNames) {\n return outletNames.reduce((outlet, outletName) => outlet || this.findOutlet(outletName), undefined);\n }\n findAll(...outletNames) {\n return outletNames.reduce((outlets, outletName) => [...outlets, ...this.findAllOutlets(outletName)], []);\n }\n getSelectorForOutletName(outletName) {\n const attributeName = this.schema.outletAttributeForScope(this.identifier, outletName);\n return this.controllerElement.getAttribute(attributeName);\n }\n findOutlet(outletName) {\n const selector = this.getSelectorForOutletName(outletName);\n if (selector)\n return this.findElement(selector, outletName);\n }\n findAllOutlets(outletName) {\n const selector = this.getSelectorForOutletName(outletName);\n return selector ? this.findAllElements(selector, outletName) : [];\n }\n findElement(selector, outletName) {\n const elements = this.scope.queryElements(selector);\n return elements.filter((element) => this.matchesElement(element, selector, outletName))[0];\n }\n findAllElements(selector, outletName) {\n const elements = this.scope.queryElements(selector);\n return elements.filter((element) => this.matchesElement(element, selector, outletName));\n }\n matchesElement(element, selector, outletName) {\n const controllerAttribute = element.getAttribute(this.scope.schema.controllerAttribute) || \"\";\n return element.matches(selector) && controllerAttribute.split(\" \").includes(outletName);\n }\n}\n\nclass Scope {\n constructor(schema, element, identifier, logger) {\n this.targets = new TargetSet(this);\n this.classes = new ClassMap(this);\n this.data = new DataMap(this);\n this.containsElement = (element) => {\n return element.closest(this.controllerSelector) === this.element;\n };\n this.schema = schema;\n this.element = element;\n this.identifier = identifier;\n this.guide = new Guide(logger);\n this.outlets = new OutletSet(this.documentScope, element);\n }\n findElement(selector) {\n return this.element.matches(selector) ? this.element : this.queryElements(selector).find(this.containsElement);\n }\n findAllElements(selector) {\n return [\n ...(this.element.matches(selector) ? [this.element] : []),\n ...this.queryElements(selector).filter(this.containsElement),\n ];\n }\n queryElements(selector) {\n return Array.from(this.element.querySelectorAll(selector));\n }\n get controllerSelector() {\n return attributeValueContainsToken(this.schema.controllerAttribute, this.identifier);\n }\n get isDocumentScope() {\n return this.element === document.documentElement;\n }\n get documentScope() {\n return this.isDocumentScope\n ? this\n : new Scope(this.schema, document.documentElement, this.identifier, this.guide.logger);\n }\n}\n\nclass ScopeObserver {\n constructor(element, schema, delegate) {\n this.element = element;\n this.schema = schema;\n this.delegate = delegate;\n this.valueListObserver = new ValueListObserver(this.element, this.controllerAttribute, this);\n this.scopesByIdentifierByElement = new WeakMap();\n this.scopeReferenceCounts = new WeakMap();\n }\n start() {\n this.valueListObserver.start();\n }\n stop() {\n this.valueListObserver.stop();\n }\n get controllerAttribute() {\n return this.schema.controllerAttribute;\n }\n parseValueForToken(token) {\n const { element, content: identifier } = token;\n const scopesByIdentifier = this.fetchScopesByIdentifierForElement(element);\n let scope = scopesByIdentifier.get(identifier);\n if (!scope) {\n scope = this.delegate.createScopeForElementAndIdentifier(element, identifier);\n scopesByIdentifier.set(identifier, scope);\n }\n return scope;\n }\n elementMatchedValue(element, value) {\n const referenceCount = (this.scopeReferenceCounts.get(value) || 0) + 1;\n this.scopeReferenceCounts.set(value, referenceCount);\n if (referenceCount == 1) {\n this.delegate.scopeConnected(value);\n }\n }\n elementUnmatchedValue(element, value) {\n const referenceCount = this.scopeReferenceCounts.get(value);\n if (referenceCount) {\n this.scopeReferenceCounts.set(value, referenceCount - 1);\n if (referenceCount == 1) {\n this.delegate.scopeDisconnected(value);\n }\n }\n }\n fetchScopesByIdentifierForElement(element) {\n let scopesByIdentifier = this.scopesByIdentifierByElement.get(element);\n if (!scopesByIdentifier) {\n scopesByIdentifier = new Map();\n this.scopesByIdentifierByElement.set(element, scopesByIdentifier);\n }\n return scopesByIdentifier;\n }\n}\n\nclass Router {\n constructor(application) {\n this.application = application;\n this.scopeObserver = new ScopeObserver(this.element, this.schema, this);\n this.scopesByIdentifier = new Multimap();\n this.modulesByIdentifier = new Map();\n }\n get element() {\n return this.application.element;\n }\n get schema() {\n return this.application.schema;\n }\n get logger() {\n return this.application.logger;\n }\n get controllerAttribute() {\n return this.schema.controllerAttribute;\n }\n get modules() {\n return Array.from(this.modulesByIdentifier.values());\n }\n get contexts() {\n return this.modules.reduce((contexts, module) => contexts.concat(module.contexts), []);\n }\n start() {\n this.scopeObserver.start();\n }\n stop() {\n this.scopeObserver.stop();\n }\n loadDefinition(definition) {\n this.unloadIdentifier(definition.identifier);\n const module = new Module(this.application, definition);\n this.connectModule(module);\n const afterLoad = definition.controllerConstructor.afterLoad;\n if (afterLoad) {\n afterLoad(definition.identifier, this.application);\n }\n }\n unloadIdentifier(identifier) {\n const module = this.modulesByIdentifier.get(identifier);\n if (module) {\n this.disconnectModule(module);\n }\n }\n getContextForElementAndIdentifier(element, identifier) {\n const module = this.modulesByIdentifier.get(identifier);\n if (module) {\n return module.contexts.find((context) => context.element == element);\n }\n }\n handleError(error, message, detail) {\n this.application.handleError(error, message, detail);\n }\n createScopeForElementAndIdentifier(element, identifier) {\n return new Scope(this.schema, element, identifier, this.logger);\n }\n scopeConnected(scope) {\n this.scopesByIdentifier.add(scope.identifier, scope);\n const module = this.modulesByIdentifier.get(scope.identifier);\n if (module) {\n module.connectContextForScope(scope);\n }\n }\n scopeDisconnected(scope) {\n this.scopesByIdentifier.delete(scope.identifier, scope);\n const module = this.modulesByIdentifier.get(scope.identifier);\n if (module) {\n module.disconnectContextForScope(scope);\n }\n }\n connectModule(module) {\n this.modulesByIdentifier.set(module.identifier, module);\n const scopes = this.scopesByIdentifier.getValuesForKey(module.identifier);\n scopes.forEach((scope) => module.connectContextForScope(scope));\n }\n disconnectModule(module) {\n this.modulesByIdentifier.delete(module.identifier);\n const scopes = this.scopesByIdentifier.getValuesForKey(module.identifier);\n scopes.forEach((scope) => module.disconnectContextForScope(scope));\n }\n}\n\nconst defaultSchema = {\n controllerAttribute: \"data-controller\",\n actionAttribute: \"data-action\",\n targetAttribute: \"data-target\",\n targetAttributeForScope: (identifier) => `data-${identifier}-target`,\n outletAttributeForScope: (identifier, outlet) => `data-${identifier}-${outlet}-outlet`,\n keyMappings: Object.assign(Object.assign({ enter: \"Enter\", tab: \"Tab\", esc: \"Escape\", space: \" \", up: \"ArrowUp\", down: \"ArrowDown\", left: \"ArrowLeft\", right: \"ArrowRight\", home: \"Home\", end: \"End\" }, objectFromEntries(\"abcdefghijklmnopqrstuvwxyz\".split(\"\").map((c) => [c, c]))), objectFromEntries(\"0123456789\".split(\"\").map((n) => [n, n]))),\n};\nfunction objectFromEntries(array) {\n return array.reduce((memo, [k, v]) => (Object.assign(Object.assign({}, memo), { [k]: v })), {});\n}\n\nclass Application {\n constructor(element = document.documentElement, schema = defaultSchema) {\n this.logger = console;\n this.debug = false;\n this.logDebugActivity = (identifier, functionName, detail = {}) => {\n if (this.debug) {\n this.logFormattedMessage(identifier, functionName, detail);\n }\n };\n this.element = element;\n this.schema = schema;\n this.dispatcher = new Dispatcher(this);\n this.router = new Router(this);\n this.actionDescriptorFilters = Object.assign({}, defaultActionDescriptorFilters);\n }\n static start(element, schema) {\n const application = new this(element, schema);\n application.start();\n return application;\n }\n async start() {\n await domReady();\n this.logDebugActivity(\"application\", \"starting\");\n this.dispatcher.start();\n this.router.start();\n this.logDebugActivity(\"application\", \"start\");\n }\n stop() {\n this.logDebugActivity(\"application\", \"stopping\");\n this.dispatcher.stop();\n this.router.stop();\n this.logDebugActivity(\"application\", \"stop\");\n }\n register(identifier, controllerConstructor) {\n this.load({ identifier, controllerConstructor });\n }\n registerActionOption(name, filter) {\n this.actionDescriptorFilters[name] = filter;\n }\n load(head, ...rest) {\n const definitions = Array.isArray(head) ? head : [head, ...rest];\n definitions.forEach((definition) => {\n if (definition.controllerConstructor.shouldLoad) {\n this.router.loadDefinition(definition);\n }\n });\n }\n unload(head, ...rest) {\n const identifiers = Array.isArray(head) ? head : [head, ...rest];\n identifiers.forEach((identifier) => this.router.unloadIdentifier(identifier));\n }\n get controllers() {\n return this.router.contexts.map((context) => context.controller);\n }\n getControllerForElementAndIdentifier(element, identifier) {\n const context = this.router.getContextForElementAndIdentifier(element, identifier);\n return context ? context.controller : null;\n }\n handleError(error, message, detail) {\n var _a;\n this.logger.error(`%s\\n\\n%o\\n\\n%o`, message, error, detail);\n (_a = window.onerror) === null || _a === void 0 ? void 0 : _a.call(window, message, \"\", 0, 0, error);\n }\n logFormattedMessage(identifier, functionName, detail = {}) {\n detail = Object.assign({ application: this }, detail);\n this.logger.groupCollapsed(`${identifier} #${functionName}`);\n this.logger.log(\"details:\", Object.assign({}, detail));\n this.logger.groupEnd();\n }\n}\nfunction domReady() {\n return new Promise((resolve) => {\n if (document.readyState == \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", () => resolve());\n }\n else {\n resolve();\n }\n });\n}\n\nfunction ClassPropertiesBlessing(constructor) {\n const classes = readInheritableStaticArrayValues(constructor, \"classes\");\n return classes.reduce((properties, classDefinition) => {\n return Object.assign(properties, propertiesForClassDefinition(classDefinition));\n }, {});\n}\nfunction propertiesForClassDefinition(key) {\n return {\n [`${key}Class`]: {\n get() {\n const { classes } = this;\n if (classes.has(key)) {\n return classes.get(key);\n }\n else {\n const attribute = classes.getAttributeName(key);\n throw new Error(`Missing attribute \"${attribute}\"`);\n }\n },\n },\n [`${key}Classes`]: {\n get() {\n return this.classes.getAll(key);\n },\n },\n [`has${capitalize(key)}Class`]: {\n get() {\n return this.classes.has(key);\n },\n },\n };\n}\n\nfunction OutletPropertiesBlessing(constructor) {\n const outlets = readInheritableStaticArrayValues(constructor, \"outlets\");\n return outlets.reduce((properties, outletDefinition) => {\n return Object.assign(properties, propertiesForOutletDefinition(outletDefinition));\n }, {});\n}\nfunction propertiesForOutletDefinition(name) {\n const camelizedName = namespaceCamelize(name);\n return {\n [`${camelizedName}Outlet`]: {\n get() {\n const outlet = this.outlets.find(name);\n if (outlet) {\n const outletController = this.application.getControllerForElementAndIdentifier(outlet, name);\n if (outletController) {\n return outletController;\n }\n else {\n throw new Error(`Missing \"data-controller=${name}\" attribute on outlet element for \"${this.identifier}\" controller`);\n }\n }\n throw new Error(`Missing outlet element \"${name}\" for \"${this.identifier}\" controller`);\n },\n },\n [`${camelizedName}Outlets`]: {\n get() {\n const outlets = this.outlets.findAll(name);\n if (outlets.length > 0) {\n return outlets\n .map((outlet) => {\n const controller = this.application.getControllerForElementAndIdentifier(outlet, name);\n if (controller) {\n return controller;\n }\n else {\n console.warn(`The provided outlet element is missing the outlet controller \"${name}\" for \"${this.identifier}\"`, outlet);\n }\n })\n .filter((controller) => controller);\n }\n return [];\n },\n },\n [`${camelizedName}OutletElement`]: {\n get() {\n const outlet = this.outlets.find(name);\n if (outlet) {\n return outlet;\n }\n else {\n throw new Error(`Missing outlet element \"${name}\" for \"${this.identifier}\" controller`);\n }\n },\n },\n [`${camelizedName}OutletElements`]: {\n get() {\n return this.outlets.findAll(name);\n },\n },\n [`has${capitalize(camelizedName)}Outlet`]: {\n get() {\n return this.outlets.has(name);\n },\n },\n };\n}\n\nfunction TargetPropertiesBlessing(constructor) {\n const targets = readInheritableStaticArrayValues(constructor, \"targets\");\n return targets.reduce((properties, targetDefinition) => {\n return Object.assign(properties, propertiesForTargetDefinition(targetDefinition));\n }, {});\n}\nfunction propertiesForTargetDefinition(name) {\n return {\n [`${name}Target`]: {\n get() {\n const target = this.targets.find(name);\n if (target) {\n return target;\n }\n else {\n throw new Error(`Missing target element \"${name}\" for \"${this.identifier}\" controller`);\n }\n },\n },\n [`${name}Targets`]: {\n get() {\n return this.targets.findAll(name);\n },\n },\n [`has${capitalize(name)}Target`]: {\n get() {\n return this.targets.has(name);\n },\n },\n };\n}\n\nfunction ValuePropertiesBlessing(constructor) {\n const valueDefinitionPairs = readInheritableStaticObjectPairs(constructor, \"values\");\n const propertyDescriptorMap = {\n valueDescriptorMap: {\n get() {\n return valueDefinitionPairs.reduce((result, valueDefinitionPair) => {\n const valueDescriptor = parseValueDefinitionPair(valueDefinitionPair, this.identifier);\n const attributeName = this.data.getAttributeNameForKey(valueDescriptor.key);\n return Object.assign(result, { [attributeName]: valueDescriptor });\n }, {});\n },\n },\n };\n return valueDefinitionPairs.reduce((properties, valueDefinitionPair) => {\n return Object.assign(properties, propertiesForValueDefinitionPair(valueDefinitionPair));\n }, propertyDescriptorMap);\n}\nfunction propertiesForValueDefinitionPair(valueDefinitionPair, controller) {\n const definition = parseValueDefinitionPair(valueDefinitionPair, controller);\n const { key, name, reader: read, writer: write } = definition;\n return {\n [name]: {\n get() {\n const value = this.data.get(key);\n if (value !== null) {\n return read(value);\n }\n else {\n return definition.defaultValue;\n }\n },\n set(value) {\n if (value === undefined) {\n this.data.delete(key);\n }\n else {\n this.data.set(key, write(value));\n }\n },\n },\n [`has${capitalize(name)}`]: {\n get() {\n return this.data.has(key) || definition.hasCustomDefaultValue;\n },\n },\n };\n}\nfunction parseValueDefinitionPair([token, typeDefinition], controller) {\n return valueDescriptorForTokenAndTypeDefinition({\n controller,\n token,\n typeDefinition,\n });\n}\nfunction parseValueTypeConstant(constant) {\n switch (constant) {\n case Array:\n return \"array\";\n case Boolean:\n return \"boolean\";\n case Number:\n return \"number\";\n case Object:\n return \"object\";\n case String:\n return \"string\";\n }\n}\nfunction parseValueTypeDefault(defaultValue) {\n switch (typeof defaultValue) {\n case \"boolean\":\n return \"boolean\";\n case \"number\":\n return \"number\";\n case \"string\":\n return \"string\";\n }\n if (Array.isArray(defaultValue))\n return \"array\";\n if (Object.prototype.toString.call(defaultValue) === \"[object Object]\")\n return \"object\";\n}\nfunction parseValueTypeObject(payload) {\n const typeFromObject = parseValueTypeConstant(payload.typeObject.type);\n if (!typeFromObject)\n return;\n const defaultValueType = parseValueTypeDefault(payload.typeObject.default);\n if (typeFromObject !== defaultValueType) {\n const propertyPath = payload.controller ? `${payload.controller}.${payload.token}` : payload.token;\n throw new Error(`The specified default value for the Stimulus Value \"${propertyPath}\" must match the defined type \"${typeFromObject}\". The provided default value of \"${payload.typeObject.default}\" is of type \"${defaultValueType}\".`);\n }\n return typeFromObject;\n}\nfunction parseValueTypeDefinition(payload) {\n const typeFromObject = parseValueTypeObject({\n controller: payload.controller,\n token: payload.token,\n typeObject: payload.typeDefinition,\n });\n const typeFromDefaultValue = parseValueTypeDefault(payload.typeDefinition);\n const typeFromConstant = parseValueTypeConstant(payload.typeDefinition);\n const type = typeFromObject || typeFromDefaultValue || typeFromConstant;\n if (type)\n return type;\n const propertyPath = payload.controller ? `${payload.controller}.${payload.typeDefinition}` : payload.token;\n throw new Error(`Unknown value type \"${propertyPath}\" for \"${payload.token}\" value`);\n}\nfunction defaultValueForDefinition(typeDefinition) {\n const constant = parseValueTypeConstant(typeDefinition);\n if (constant)\n return defaultValuesByType[constant];\n const defaultValue = typeDefinition.default;\n if (defaultValue !== undefined)\n return defaultValue;\n return typeDefinition;\n}\nfunction valueDescriptorForTokenAndTypeDefinition(payload) {\n const key = `${dasherize(payload.token)}-value`;\n const type = parseValueTypeDefinition(payload);\n return {\n type,\n key,\n name: camelize(key),\n get defaultValue() {\n return defaultValueForDefinition(payload.typeDefinition);\n },\n get hasCustomDefaultValue() {\n return parseValueTypeDefault(payload.typeDefinition) !== undefined;\n },\n reader: readers[type],\n writer: writers[type] || writers.default,\n };\n}\nconst defaultValuesByType = {\n get array() {\n return [];\n },\n boolean: false,\n number: 0,\n get object() {\n return {};\n },\n string: \"\",\n};\nconst readers = {\n array(value) {\n const array = JSON.parse(value);\n if (!Array.isArray(array)) {\n throw new TypeError(`expected value of type \"array\" but instead got value \"${value}\" of type \"${parseValueTypeDefault(array)}\"`);\n }\n return array;\n },\n boolean(value) {\n return !(value == \"0\" || String(value).toLowerCase() == \"false\");\n },\n number(value) {\n return Number(value);\n },\n object(value) {\n const object = JSON.parse(value);\n if (object === null || typeof object != \"object\" || Array.isArray(object)) {\n throw new TypeError(`expected value of type \"object\" but instead got value \"${value}\" of type \"${parseValueTypeDefault(object)}\"`);\n }\n return object;\n },\n string(value) {\n return value;\n },\n};\nconst writers = {\n default: writeString,\n array: writeJSON,\n object: writeJSON,\n};\nfunction writeJSON(value) {\n return JSON.stringify(value);\n}\nfunction writeString(value) {\n return `${value}`;\n}\n\nclass Controller {\n constructor(context) {\n this.context = context;\n }\n static get shouldLoad() {\n return true;\n }\n static afterLoad(_identifier, _application) {\n return;\n }\n get application() {\n return this.context.application;\n }\n get scope() {\n return this.context.scope;\n }\n get element() {\n return this.scope.element;\n }\n get identifier() {\n return this.scope.identifier;\n }\n get targets() {\n return this.scope.targets;\n }\n get outlets() {\n return this.scope.outlets;\n }\n get classes() {\n return this.scope.classes;\n }\n get data() {\n return this.scope.data;\n }\n initialize() {\n }\n connect() {\n }\n disconnect() {\n }\n dispatch(eventName, { target = this.element, detail = {}, prefix = this.identifier, bubbles = true, cancelable = true } = {}) {\n const type = prefix ? `${prefix}:${eventName}` : eventName;\n const event = new CustomEvent(type, { detail, bubbles, cancelable });\n target.dispatchEvent(event);\n return event;\n }\n}\nController.blessings = [\n ClassPropertiesBlessing,\n TargetPropertiesBlessing,\n ValuePropertiesBlessing,\n OutletPropertiesBlessing,\n];\nController.targets = [];\nController.outlets = [];\nController.values = {};\n\nexport { Application, AttributeObserver, Context, Controller, ElementObserver, IndexedMultimap, Multimap, SelectorObserver, StringMapObserver, TokenListObserver, ValueListObserver, add, defaultSchema, del, fetch, prune };\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport default class extends Controller {\n // static targets = ['template', 'associations', 'fields', 'newFields'];\n // Some applications don't compile correctly with the usual static syntax.\n // Thus implementing targets with standard getters below\n\n static targets = [\"template\", \"associations\", \"fields\", \"newFields\"];\n\n connect() {\n console.log(\"Abyme Connected\");\n\n if (this.count) {\n // If data-count is present,\n // add n default fields on page load\n\n this.add_default_associations();\n }\n }\n\n // return the value of the data-count attribute\n\n get count() {\n return this.element.dataset.minCount || 0;\n }\n\n // return the value of the data-position attribute\n // if there is no position specified set end as default\n\n get position() {\n return this.associationsTarget.dataset.abymePosition === \"end\"\n ? \"beforeend\"\n : \"afterbegin\";\n }\n\n // ADD_ASSOCIATION\n\n // this function is call whenever a click occurs\n // on the element with the click->abyme#add_association\n // <button> element by default\n\n // if a data-count is present the add_association\n // will be call without an event so we have to check\n // this case\n\n // check for limit reached\n // dispatch an event if the limit is reached\n\n // - call the function build_html that take care\n // for building the correct html to be inserted in the DOM\n // - dispatch an event before insert\n // - insert html into the dom\n // - dispatch an event after insert\n\n add_association(event) {\n if (event) {\n event.preventDefault();\n }\n\n if (this.element.dataset.limit && this.limit_check()) {\n this.create_event(\"limit-reached\");\n return false;\n }\n\n const html = this.build_html();\n this.create_event(\"before-add\");\n this.associationsTarget.insertAdjacentHTML(this.position, html);\n this.create_event(\"after-add\");\n }\n\n // REMOVE_ASSOCIATION\n\n // this function is call whenever a click occurs\n // on the element with the click->abyme#remove_association\n // <button> element by default\n\n // - call the function mark_for_destroy that takes care\n // of marking the element for destruction and hiding it\n // - dispatch an event before mark & hide\n // - mark for descrution + hide the element\n // - dispatch an event after mark and hide\n\n remove_association(event) {\n event.preventDefault();\n\n this.create_event(\"before-remove\");\n this.mark_for_destroy(event);\n this.create_event(\"after-remove\");\n }\n\n // LIFECYCLE EVENTS RELATED\n\n // CREATE_EVENT\n\n // take a stage (String) => before-add, after-add...\n // create a new custom event\n // and dispatch at at the controller level\n\n create_event(stage, html = null) {\n const event = new CustomEvent(`abyme:${stage}`, {\n detail: { controller: this, content: html },\n });\n this.element.dispatchEvent(event);\n // WIP\n this.dispatch(event, stage);\n }\n\n // WIP : Trying to integrate event handling through controller inheritance\n dispatch(event, stage) {\n if (stage === \"before-add\" && this.abymeBeforeAdd)\n this.abymeBeforeAdd(event);\n if (stage === \"after-add\" && this.abymeAfterAdd) this.abymeAfterAdd(event);\n if (stage === \"before-remove\" && this.abymeBeforeRemove)\n this.abymeBeforeAdd(event);\n if (stage === \"after-remove\" && this.abymeAfterRemove)\n this.abymeAfterRemove(event);\n }\n\n abymeBeforeAdd(event) {}\n\n abymeAfterAdd(event) {}\n\n abymeBeforeRemove(event) {}\n\n abymeAfterRemove(event) {}\n\n // BUILD HTML\n\n // takes the html template and substitutes the sub-string\n // NEW_RECORD for a generated timestamp\n // then if there is a sub template in the html (multiple nested level)\n // set all the sub timestamps back as NEW_RECORD\n // finally returns the html\n\n build_html() {\n let html = this.templateTarget.innerHTML.replace(\n /NEW_RECORD/g,\n new Date().getTime()\n );\n\n if (html.match(/<template[\\s\\S]+<\\/template>/)) {\n const template = html\n .match(/<template[\\s\\S]+<\\/template>/)[0]\n .replace(/(\\[\\d{12,}\\])(\\[[^\\[\\]]+\\]\"){1}/g, `[NEW_RECORD]$2`);\n\n html = html.replace(/<template[\\s\\S]+<\\/template>/g, template);\n }\n\n return html;\n }\n\n // MARK_FOR_DESTROY\n\n // mark association for destruction\n // get the closest abyme--fields from the remove_association button\n // set the _destroy input value as 1\n // hide the element\n // add the class of abyme--marked-for-destroy to the element\n\n mark_for_destroy(event) {\n let item = event.target.closest(\".abyme--fields\");\n item.querySelector(\"input[name*='_destroy']\").value = 1;\n item.style.display = \"none\";\n item.classList.add(\"abyme--marked-for-destroy\");\n }\n\n // LIMIT_CHECK\n\n // Check if associations limit is reached\n // based on newFieldsTargets only\n // persisted fields are ignored\n\n limit_check() {\n return (\n this.newFieldsTargets.filter(\n (item) => !item.classList.contains(\"abyme--marked-for-destroy\")\n ).length >= parseInt(this.element.dataset.limit)\n );\n }\n\n // ADD_DEFAULT_ASSOCIATION\n\n // Add n default blank associations at page load\n // call sleep function to ensure uniqueness of timestamp\n\n async add_default_associations() {\n let i = 0;\n while (i < this.count) {\n this.add_association();\n i++;\n await this.sleep(1);\n }\n }\n\n sleep(ms) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n"],"names":["camelize","value","replace","_","char","toUpperCase","capitalize","charAt","slice","readInheritableStaticArrayValues","constructor","propertyName","ancestors","getAncestorsForConstructor","Array","from","reduce","values","definition","isArray","getOwnStaticArrayValues","forEach","name","add","Set","push","Object","getPrototypeOf","reverse","objectFromEntries","array","memo","k","v","assign","parseValueDefinitionPair","token","typeDefinition","controller","payload","key","toLowerCase","type","typeFromObject","parseValueTypeConstant","typeObject","defaultValueType","parseValueTypeDefault","default","Error","parseValueTypeObject","typeFromDefaultValue","typeFromConstant","parseValueTypeDefinition","defaultValue","constant","defaultValuesByType","undefined","defaultValueForDefinition","hasCustomDefaultValue","reader","readers","writer","writers","valueDescriptorForTokenAndTypeDefinition","Boolean","Number","String","prototype","toString","call","b","extended","Reflect","construct","arguments","create","setPrototypeOf","extendWithReflect","this","a","testReflectExtension","error","enter","tab","esc","space","up","down","left","right","home","end","split","map","c","n","boolean","number","object","string","JSON","parse","TypeError","writeJSON","stringify","Controller","context","shouldLoad","static","_identifier","_application","application","scope","element","identifier","targets","outlets","classes","data","initialize","connect","disconnect","dispatch","eventName","target","detail","prefix","bubbles","cancelable","event","CustomEvent","dispatchEvent","_settle","pact","state","s","_Pact","o","bind","then","observer","blessings","properties","classDefinition","get","has","attribute","getAttributeName","getAll","targetDefinition","find","findAll","valueDefinitionPairs","pairs","keys","getOwnStaticObjectPairs","readInheritableStaticObjectPairs","propertyDescriptorMap","valueDescriptorMap","result","valueDefinitionPair","valueDescriptor","attributeName","getAttributeNameForKey","propertiesForValueDefinitionPair","read","write","set","delete","outletDefinition","camelizedName","outlet","outletController","getControllerForElementAndIdentifier","length","console","warn","filter","propertiesForOutletDefinition","log","count","add_default_associations","add_association","preventDefault","dataset","limit","limit_check","create_event","html","build_html","associationsTarget","insertAdjacentHTML","position","remove_association","mark_for_destroy","stage","content","abymeBeforeAdd","abymeAfterAdd","abymeBeforeRemove","abymeAfterRemove","templateTarget","innerHTML","Date","getTime","match","template","item","closest","querySelector","style","display","classList","newFieldsTargets","contains","parseInt","i","test","update","body","shouldContinue","_isSettledPact","reject","_resumeAfterTest","_resumeAfterBody","updateValue","_this2","sleep","ms","Promise","resolve","setTimeout","minCount","abymePosition","onFulfilled","onRejected","callback","e","_this","thenable"],"mappings":"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"}
data/lib/abyme/version.rb CHANGED
@@ -2,8 +2,8 @@
2
2
  module Abyme
3
3
  module VERSION
4
4
  MAJOR = 0
5
- MINOR = 6
6
- PATCH = 6
5
+ MINOR = 7
6
+ PATCH = 0
7
7
 
8
8
  STRING = [MAJOR, MINOR, PATCH].join(".")
9
9
  end
@@ -1,5 +1,5 @@
1
1
  {
2
- "systemParams": "darwin-x64-93",
2
+ "systemParams": "darwin-x64-83",
3
3
  "modulesFolders": [
4
4
  "node_modules"
5
5
  ],
@@ -20,7 +20,7 @@
20
20
  "jest@^26.6.3",
21
21
  "microbundle@^0.13.0",
22
22
  "mutationobserver-shim@^0.3.7",
23
- "stimulus@^2.0.0"
23
+ "stimulus@^3.0.0"
24
24
  ],
25
25
  "lockfileEntries": {
26
26
  "@babel/code-frame@^7.0.0": "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431",
@@ -262,6 +262,8 @@
262
262
  "@babel/types@^7.4.4": "https://registry.yarnpkg.com/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba",
263
263
  "@bcoe/v8-coverage@^0.2.3": "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39",
264
264
  "@cnakazawa/watch@^1.0.3": "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a",
265
+ "@hotwired/stimulus-webpack-helpers@^1.0.0": "https://registry.yarnpkg.com/@hotwired/stimulus-webpack-helpers/-/stimulus-webpack-helpers-1.0.1.tgz#4cd74487adeca576c9865ac2b9fe5cb20cef16dd",
266
+ "@hotwired/stimulus@^3.2.1": "https://registry.yarnpkg.com/@hotwired/stimulus/-/stimulus-3.2.1.tgz#e3de23623b0c52c247aba4cd5d530d257008676b",
265
267
  "@istanbuljs/load-nyc-config@^1.0.0": "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced",
266
268
  "@istanbuljs/schema@^0.1.2": "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98",
267
269
  "@jest/console@^26.6.2": "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2",
@@ -294,10 +296,6 @@
294
296
  "@sindresorhus/is@^0.14.0": "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea",
295
297
  "@sinonjs/commons@^1.7.0": "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d",
296
298
  "@sinonjs/fake-timers@^6.0.1": "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40",
297
- "@stimulus/core@^2.0.0": "https://registry.yarnpkg.com/@stimulus/core/-/core-2.0.0.tgz#140c85318d6a8a8210c0faf182223b8459348877",
298
- "@stimulus/multimap@^2.0.0": "https://registry.yarnpkg.com/@stimulus/multimap/-/multimap-2.0.0.tgz#420cfa096ed6538df4a91dbd2b2842c1779952b2",
299
- "@stimulus/mutation-observers@^2.0.0": "https://registry.yarnpkg.com/@stimulus/mutation-observers/-/mutation-observers-2.0.0.tgz#3dbe37453bda47a6c795a90204ee8d77a799fb87",
300
- "@stimulus/webpack-helpers@^2.0.0": "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-2.0.0.tgz#54296d2a2dffd4f962d2e802d99a3fdd84b8845f",
301
299
  "@szmarczak/http-timer@^1.1.2": "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421",
302
300
  "@testing-library/dom@^7.29.6": "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.31.2.tgz#df361db38f5212b88555068ab8119f5d841a8c4a",
303
301
  "@tootallnate/once@1": "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82",
@@ -1126,7 +1124,7 @@
1126
1124
  "stack-utils@^2.0.2": "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5",
1127
1125
  "standard-pkg@^0.5.0": "https://registry.yarnpkg.com/standard-pkg/-/standard-pkg-0.5.0.tgz#2fa2d858d5dbb99ce7aae7cea6e4bbeeaabc55d5",
1128
1126
  "static-extend@^0.1.1": "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6",
1129
- "stimulus@^2.0.0": "https://registry.yarnpkg.com/stimulus/-/stimulus-2.0.0.tgz#713c8b91a72ef90914b90955f0e705f004403047",
1127
+ "stimulus@^3.0.0": "https://registry.yarnpkg.com/stimulus/-/stimulus-3.2.1.tgz#bf049a4379ed4ff7475515acce1f0b6fa15a0187",
1130
1128
  "string-hash@^1.1.1": "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b",
1131
1129
  "string-length@^4.0.1": "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a",
1132
1130
  "string-width@^1.0.1": "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3",
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abyme",
3
- "version": "0.6.6",
3
+ "version": "0.7.0",
4
4
  "description": "JS companion to abyme gem",
5
5
  "files": [
6
6
  "package.json",
@@ -16,7 +16,7 @@
16
16
  "homepage": "https://github.com/bear-in-mind/abyme",
17
17
  "bugs": "https://github.com/bear-in-mind/abyme/issues",
18
18
  "dependencies": {
19
- "stimulus": "^2.0.0"
19
+ "stimulus": "^3.0.0"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@babel/core": "7.11.6",
@@ -1,14 +1,14 @@
1
- import { Controller } from 'stimulus';
1
+ import { Controller } from "@hotwired/stimulus";
2
2
 
3
3
  export default class extends Controller {
4
4
  // static targets = ['template', 'associations', 'fields', 'newFields'];
5
- // Some applications don't compile correctly with the usual static syntax.
5
+ // Some applications don't compile correctly with the usual static syntax.
6
6
  // Thus implementing targets with standard getters below
7
7
 
8
- static targets = ['template', 'associations', 'fields', 'newFields']
8
+ static targets = ["template", "associations", "fields", "newFields"];
9
9
 
10
10
  connect() {
11
- console.log("Abyme Connected")
11
+ console.log("Abyme Connected");
12
12
 
13
13
  if (this.count) {
14
14
  // If data-count is present,
@@ -23,12 +23,14 @@ export default class extends Controller {
23
23
  get count() {
24
24
  return this.element.dataset.minCount || 0;
25
25
  }
26
-
26
+
27
27
  // return the value of the data-position attribute
28
28
  // if there is no position specified set end as default
29
29
 
30
30
  get position() {
31
- return this.associationsTarget.dataset.abymePosition === 'end' ? 'beforeend' : 'afterbegin';
31
+ return this.associationsTarget.dataset.abymePosition === "end"
32
+ ? "beforeend"
33
+ : "afterbegin";
32
34
  }
33
35
 
34
36
  // ADD_ASSOCIATION
@@ -41,7 +43,7 @@ export default class extends Controller {
41
43
  // will be call without an event so we have to check
42
44
  // this case
43
45
 
44
- // check for limit reached
46
+ // check for limit reached
45
47
  // dispatch an event if the limit is reached
46
48
 
47
49
  // - call the function build_html that take care
@@ -56,14 +58,14 @@ export default class extends Controller {
56
58
  }
57
59
 
58
60
  if (this.element.dataset.limit && this.limit_check()) {
59
- this.create_event('limit-reached')
60
- return false
61
+ this.create_event("limit-reached");
62
+ return false;
61
63
  }
62
64
 
63
65
  const html = this.build_html();
64
- this.create_event('before-add');
66
+ this.create_event("before-add");
65
67
  this.associationsTarget.insertAdjacentHTML(this.position, html);
66
- this.create_event('after-add');
68
+ this.create_event("after-add");
67
69
  }
68
70
 
69
71
  // REMOVE_ASSOCIATION
@@ -81,9 +83,9 @@ export default class extends Controller {
81
83
  remove_association(event) {
82
84
  event.preventDefault();
83
85
 
84
- this.create_event('before-remove');
86
+ this.create_event("before-remove");
85
87
  this.mark_for_destroy(event);
86
- this.create_event('after-remove');
88
+ this.create_event("after-remove");
87
89
  }
88
90
 
89
91
  // LIFECYCLE EVENTS RELATED
@@ -91,11 +93,13 @@ export default class extends Controller {
91
93
  // CREATE_EVENT
92
94
 
93
95
  // take a stage (String) => before-add, after-add...
94
- // create a new custom event
96
+ // create a new custom event
95
97
  // and dispatch at at the controller level
96
98
 
97
99
  create_event(stage, html = null) {
98
- const event = new CustomEvent(`abyme:${stage}`, { detail: {controller: this, content: html} });
100
+ const event = new CustomEvent(`abyme:${stage}`, {
101
+ detail: { controller: this, content: html },
102
+ });
99
103
  this.element.dispatchEvent(event);
100
104
  // WIP
101
105
  this.dispatch(event, stage);
@@ -103,23 +107,22 @@ export default class extends Controller {
103
107
 
104
108
  // WIP : Trying to integrate event handling through controller inheritance
105
109
  dispatch(event, stage) {
106
- if (stage === 'before-add' && this.abymeBeforeAdd) this.abymeBeforeAdd(event);
107
- if (stage === 'after-add' && this.abymeAfterAdd) this.abymeAfterAdd(event);
108
- if (stage === 'before-remove' && this.abymeBeforeRemove) this.abymeBeforeAdd(event);
109
- if (stage === 'after-remove' && this.abymeAfterRemove) this.abymeAfterRemove(event);
110
+ if (stage === "before-add" && this.abymeBeforeAdd)
111
+ this.abymeBeforeAdd(event);
112
+ if (stage === "after-add" && this.abymeAfterAdd) this.abymeAfterAdd(event);
113
+ if (stage === "before-remove" && this.abymeBeforeRemove)
114
+ this.abymeBeforeAdd(event);
115
+ if (stage === "after-remove" && this.abymeAfterRemove)
116
+ this.abymeAfterRemove(event);
110
117
  }
111
118
 
112
- abymeBeforeAdd(event) {
113
- }
119
+ abymeBeforeAdd(event) {}
114
120
 
115
- abymeAfterAdd(event) {
116
- }
121
+ abymeAfterAdd(event) {}
117
122
 
118
- abymeBeforeRemove(event) {
119
- }
123
+ abymeBeforeRemove(event) {}
120
124
 
121
- abymeAfterRemove(event) {
122
- }
125
+ abymeAfterRemove(event) {}
123
126
 
124
127
  // BUILD HTML
125
128
 
@@ -127,25 +130,25 @@ export default class extends Controller {
127
130
  // NEW_RECORD for a generated timestamp
128
131
  // then if there is a sub template in the html (multiple nested level)
129
132
  // set all the sub timestamps back as NEW_RECORD
130
- // finally returns the html
133
+ // finally returns the html
131
134
 
132
135
  build_html() {
133
136
  let html = this.templateTarget.innerHTML.replace(
134
137
  /NEW_RECORD/g,
135
138
  new Date().getTime()
136
139
  );
137
-
140
+
138
141
  if (html.match(/<template[\s\S]+<\/template>/)) {
139
142
  const template = html
140
- .match(/<template[\s\S]+<\/template>/)[0]
141
- .replace(/(\[\d{12,}\])(\[[^\[\]]+\]"){1}/g, `[NEW_RECORD]$2`);
142
-
143
+ .match(/<template[\s\S]+<\/template>/)[0]
144
+ .replace(/(\[\d{12,}\])(\[[^\[\]]+\]"){1}/g, `[NEW_RECORD]$2`);
145
+
143
146
  html = html.replace(/<template[\s\S]+<\/template>/g, template);
144
147
  }
145
148
 
146
149
  return html;
147
150
  }
148
-
151
+
149
152
  // MARK_FOR_DESTROY
150
153
 
151
154
  // mark association for destruction
@@ -155,13 +158,12 @@ export default class extends Controller {
155
158
  // add the class of abyme--marked-for-destroy to the element
156
159
 
157
160
  mark_for_destroy(event) {
158
- let item = event.target.closest('.abyme--fields');
161
+ let item = event.target.closest(".abyme--fields");
159
162
  item.querySelector("input[name*='_destroy']").value = 1;
160
- item.style.display = 'none';
161
- item.classList.add('abyme--marked-for-destroy')
163
+ item.style.display = "none";
164
+ item.classList.add("abyme--marked-for-destroy");
162
165
  }
163
166
 
164
-
165
167
  // LIMIT_CHECK
166
168
 
167
169
  // Check if associations limit is reached
@@ -169,9 +171,11 @@ export default class extends Controller {
169
171
  // persisted fields are ignored
170
172
 
171
173
  limit_check() {
172
- return (this.newFieldsTargets
173
- .filter(item => !item.classList.contains('abyme--marked-for-destroy'))).length
174
- >= parseInt(this.element.dataset.limit)
174
+ return (
175
+ this.newFieldsTargets.filter(
176
+ (item) => !item.classList.contains("abyme--marked-for-destroy")
177
+ ).length >= parseInt(this.element.dataset.limit)
178
+ );
175
179
  }
176
180
 
177
181
  // ADD_DEFAULT_ASSOCIATION
@@ -180,15 +184,15 @@ export default class extends Controller {
180
184
  // call sleep function to ensure uniqueness of timestamp
181
185
 
182
186
  async add_default_associations() {
183
- let i = 0
187
+ let i = 0;
184
188
  while (i < this.count) {
185
- this.add_association()
186
- i++
189
+ this.add_association();
190
+ i++;
187
191
  await this.sleep(1);
188
192
  }
189
193
  }
190
194
 
191
195
  sleep(ms) {
192
- return new Promise(resolve => setTimeout(resolve, ms));
196
+ return new Promise((resolve) => setTimeout(resolve, ms));
193
197
  }
194
198
  }