turbo_boost-streams 0.1.10 → 0.1.11

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0176014a9a4f4408fd302e6770f521a4b64555d991763a6e159bf3ed8dee8665
4
- data.tar.gz: 9262f3ebed4bbe83239b6c80429f8688e0fca9850bcf862b5f85f4b0830d7e93
3
+ metadata.gz: e3cd0b5ecb50af5027d5a3f23cc5655ae4c452cea18c6fbbbc28111226cb573a
4
+ data.tar.gz: 5afc982714bc9bf11bf65c4d38a67ca8352ba73b3a88eedeab80fb11aa04e2bd
5
5
  SHA512:
6
- metadata.gz: 78c9efc73f4d8a56e68c259e230b9a75f4ccac0d14c9630fe4c64779116be412d09dcd1c0eb157648c59c91074afbeeea2276ee35a55a5333d6c670a08528103
7
- data.tar.gz: 4ed333da280c1116585df6ea0d7aafef4ba57aa41527f4f19642fd04f7425be552816f3bbb8127b598341f7c5dce5d694da0da80664b33f2f5e9a522a956539b
6
+ metadata.gz: e5c6acc8d34d91a32bdc61fc8d15469a008ff4a6cbceb198bae13ec2c6cd16ef5b2ff54a764fa424a916c3e9beed67574d9274c8a8959f00580fa1492a39a53f
7
+ data.tar.gz: 968ba1e35a583a552ee1368f5f6c5219f5c4930388fc63974408cbc1198d004c31ced0bdfe3fa14c6418082eb0e6fec8ee60064d16fb158bff272e36d68d8e26
data/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  </h1>
9
9
  <p align="center">
10
10
  <a href="http://blog.codinghorror.com/the-best-code-is-no-code-at-all/">
11
- <img alt="Lines of Code" src="https://img.shields.io/badge/loc-261-47d299.svg" />
11
+ <img alt="Lines of Code" src="https://img.shields.io/badge/loc-295-47d299.svg" />
12
12
  </a>
13
13
  <a href="https://codeclimate.com/github/hopsoft/turbo_boost-streams/maintainability">
14
14
  <img src="https://api.codeclimate.com/v1/badges/a6671f4294ec0f21f732/maintainability" />
@@ -79,6 +79,8 @@ You can `invoke` any DOM method on the client with Turbo Streams.
79
79
  - [Usage](#usage)
80
80
  - [Method Chaining](#method-chaining)
81
81
  - [Event Dispatch](#event-dispatch)
82
+ - [Morph](#morph)
83
+ - [Morph Method](#morph-method)
82
84
  - [Syntax Styles](#syntax-styles)
83
85
  - [Extending Behavior](#extending-behavior)
84
86
  - [Implementation Details](#implementation-details)
@@ -193,6 +195,56 @@ turbo_stream
193
195
  .invoke(:dispatch_event, args: ["turbo-ready:demo", {bubbles: true, detail: {...}}]) # set event options
194
196
  ```
195
197
 
198
+ ### Morph
199
+
200
+ You can morph elements with the `morph` method.
201
+
202
+ ```ruby
203
+ turbo_stream.invoke(:morph, args: [render("path/to/partial")], selector: "#my-element")
204
+ ```
205
+
206
+ > [!NOTE]
207
+ > TurboBoost Streams uses [Idiomorph](https://github.com/bigskysoftware/idiomorph) for morphing.
208
+
209
+ The following options are used to morph elements.
210
+
211
+ ```js
212
+ {
213
+ morphStyle: 'outerHTML',
214
+ ignoreActiveValue: true,
215
+ head: { style: 'merge' },
216
+ callbacks: { beforeNodeMorphed: (oldNode, _) => ... }
217
+ }
218
+ ```
219
+
220
+ > [!TIP]
221
+ > The callbacks honor the `data-turbo-permanent` attribute and is aware of the [Trix](https://trix-editor.org/) editor.
222
+
223
+ ### Morph Method
224
+
225
+ The morph method is also exported to the `TurboBoost.Streams` global and is available for client side morphing.
226
+
227
+ ```js
228
+ TurboBoost.Streams.morph.method // → function(targetNode, htmlString, options = {})
229
+ ```
230
+
231
+ You can also override the `morph` method if desired.
232
+
233
+ ```js
234
+ TurboBoost.Streams.morph.method = (targetNode, htmlString, options = {}) => {
235
+ // your custom implementation
236
+ }
237
+ ```
238
+
239
+ It also support adding a delay before morphing is performed.
240
+
241
+ ```js
242
+ TurboBoost.Streams.morph.delay = 50 // → 50ms
243
+ ```
244
+
245
+ > [!TIP]
246
+ > Complex test suites may require a delay to ensure the DOM is ready before morphing.
247
+
196
248
  ### Syntax Styles
197
249
 
198
250
  You can use [`snake_case`](https://en.wikipedia.org/wiki/Snake_case) when invoking DOM functionality.
@@ -217,21 +269,12 @@ If you add new capabilities to the browser, you can control them from the server
217
269
  // JavaScript on the client
218
270
  import morphdom from 'morphdom'
219
271
 
220
- window.MyNamespace = {
221
- morph: (from, to, options = {}) => {
222
- morphdom(document.querySelector(from), to, options)
223
- }
224
- }
272
+ window.MyNamespace = { coolStuff: (arg) => { ... } }
225
273
  ```
226
274
 
227
275
  ```ruby
228
276
  # Ruby on the server
229
- turbo_stream.invoke "MyNamespace.morph",
230
- args: [
231
- "#demo",
232
- "<div id='demo'><p>You've changed...</p></div>",
233
- {children_only: true}
234
- ]
277
+ turbo_stream.invoke "MyNamespace.coolStuff", args: ["Hello World!"]
235
278
  ```
236
279
 
237
280
  ### Implementation Details
@@ -1,2 +1,2 @@
1
- var le=Object.defineProperty,ae=Object.defineProperties;var oe=Object.getOwnPropertyDescriptors;var F=Object.getOwnPropertySymbols;var se=Object.prototype.hasOwnProperty,ue=Object.prototype.propertyIsEnumerable;var q=(a,o,u)=>o in a?le(a,o,{enumerable:!0,configurable:!0,writable:!0,value:u}):a[o]=u,V=(a,o)=>{for(var u in o||(o={}))se.call(o,u)&&q(a,u,o[u]);if(F)for(var u of F(o))ue.call(o,u)&&q(a,u,o[u]);return a},U=(a,o)=>ae(a,oe(o));var W="0.1.10";var fe={turboPermanentAttribute:"data-turbo-permanent"},w=V({},fe);var _=function(){"use strict";let a=new Set,o={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:A,afterNodeAdded:A,beforeNodeMorphed:A,afterNodeMorphed:A,beforeNodeRemoved:A,afterNodeRemoved:A,beforeAttributeUpdated:A},head:{style:"merge",shouldPreserve:function(e){return e.getAttribute("im-preserve")==="true"},shouldReAppend:function(e){return e.getAttribute("im-re-append")==="true"},shouldRemove:A,afterHeadMorphed:A}};function u(e,t,r={}){e instanceof Document&&(e=e.documentElement),typeof t=="string"&&(t=K(t));let n=Q(t),i=J(e,n,r);return p(e,n,i)}function p(e,t,r){if(r.head.block){let n=e.querySelector("head"),i=t.querySelector("head");if(n&&i){let l=T(i,n,r);Promise.all(l).then(function(){p(e,t,Object.assign(r,{head:{block:!1,ignore:!0}}))});return}}if(r.morphStyle==="innerHTML")return b(t,e,r),e.children;if(r.morphStyle==="outerHTML"||r.morphStyle==null){let n=x(t,e,r),i=n==null?void 0:n.previousSibling,l=n==null?void 0:n.nextSibling,s=f(e,n,r);return n?Z(i,s,l):[]}else throw"Do not understand how to morph style "+r.morphStyle}function d(e,t){return t.ignoreActiveValue&&e===document.activeElement&&e!==document.body}function f(e,t,r){if(!(r.ignoreActive&&e===document.activeElement))return t==null?r.callbacks.beforeNodeRemoved(e)===!1?e:(e.remove(),r.callbacks.afterNodeRemoved(e),null):R(e,t)?(r.callbacks.beforeNodeMorphed(e,t)===!1||(e instanceof HTMLHeadElement&&r.head.ignore||(e instanceof HTMLHeadElement&&r.head.style!=="morph"?T(t,e,r):(g(t,e,r),d(e,r)||b(t,e,r))),r.callbacks.afterNodeMorphed(e,t)),e):r.callbacks.beforeNodeRemoved(e)===!1||r.callbacks.beforeNodeAdded(t)===!1?e:(e.parentElement.replaceChild(t,e),r.callbacks.afterNodeAdded(t),r.callbacks.afterNodeRemoved(e),t)}function b(e,t,r){let n=e.firstChild,i=t.firstChild,l;for(;n;){if(l=n,n=l.nextSibling,i==null){if(r.callbacks.beforeNodeAdded(l)===!1)return;t.appendChild(l),r.callbacks.afterNodeAdded(l),S(r,l);continue}if(C(l,i,r)){f(i,l,r),i=i.nextSibling,S(r,l);continue}let s=Y(e,t,l,i,r);if(s){i=P(i,s,r),f(s,l,r),S(r,l);continue}let m=G(e,t,l,i,r);if(m){i=P(i,m,r),f(m,l,r),S(r,l);continue}if(r.callbacks.beforeNodeAdded(l)===!1)return;t.insertBefore(l,i),r.callbacks.afterNodeAdded(l),S(r,l)}for(;i!==null;){let s=i;i=i.nextSibling,j(s,r)}}function c(e,t,r,n){return e==="value"&&n.ignoreActiveValue&&t===document.activeElement?!0:n.callbacks.beforeAttributeUpdated(e,t,r)===!1}function g(e,t,r){let n=e.nodeType;if(n===1){let i=e.attributes,l=t.attributes;for(let s of i)c(s.name,t,"update",r)||t.getAttribute(s.name)!==s.value&&t.setAttribute(s.name,s.value);for(let s=l.length-1;0<=s;s--){let m=l[s];c(m.name,t,"remove",r)||e.hasAttribute(m.name)||t.removeAttribute(m.name)}}(n===8||n===3)&&t.nodeValue!==e.nodeValue&&(t.nodeValue=e.nodeValue),d(t,r)||H(e,t,r)}function v(e,t,r,n){if(e[r]!==t[r]){let i=c(r,t,"update",n);i||(t[r]=e[r]),e[r]?i||t.setAttribute(r,e[r]):c(r,t,"remove",n)||t.removeAttribute(r)}}function H(e,t,r){if(e instanceof HTMLInputElement&&t instanceof HTMLInputElement&&e.type!=="file"){let n=e.value,i=t.value;v(e,t,"checked",r),v(e,t,"disabled",r),e.hasAttribute("value")?n!==i&&(c("value",t,"update",r)||(t.setAttribute("value",n),t.value=n)):c("value",t,"remove",r)||(t.value="",t.removeAttribute("value"))}else if(e instanceof HTMLOptionElement)v(e,t,"selected",r);else if(e instanceof HTMLTextAreaElement&&t instanceof HTMLTextAreaElement){let n=e.value,i=t.value;if(c("value",t,"update",r))return;n!==i&&(t.value=n),t.firstChild&&t.firstChild.nodeValue!==n&&(t.firstChild.nodeValue=n)}}function T(e,t,r){let n=[],i=[],l=[],s=[],m=r.head.style,y=new Map;for(let h of e.children)y.set(h.outerHTML,h);for(let h of t.children){let E=y.has(h.outerHTML),I=r.head.shouldReAppend(h),L=r.head.shouldPreserve(h);E||L?I?i.push(h):(y.delete(h.outerHTML),l.push(h)):m==="append"?I&&(i.push(h),s.push(h)):r.head.shouldRemove(h)!==!1&&i.push(h)}s.push(...y.values());let N=[];for(let h of s){let E=document.createRange().createContextualFragment(h.outerHTML).firstChild;if(r.callbacks.beforeNodeAdded(E)!==!1){if(E.href||E.src){let I=null,L=new Promise(function(ie){I=ie});E.addEventListener("load",function(){I()}),N.push(L)}t.appendChild(E),r.callbacks.afterNodeAdded(E),n.push(E)}}for(let h of i)r.callbacks.beforeNodeRemoved(h)!==!1&&(t.removeChild(h),r.callbacks.afterNodeRemoved(h));return r.head.afterHeadMorphed(t,{added:n,kept:l,removed:i}),N}function ye(){}function A(){}function z(e){let t={};return Object.assign(t,o),Object.assign(t,e),t.callbacks={},Object.assign(t.callbacks,o.callbacks),Object.assign(t.callbacks,e.callbacks),t.head={},Object.assign(t.head,o.head),Object.assign(t.head,e.head),t}function J(e,t,r){return r=z(r),{target:e,newContent:t,config:r,morphStyle:r.morphStyle,ignoreActive:r.ignoreActive,ignoreActiveValue:r.ignoreActiveValue,idMap:ne(e,t),deadIds:new Set,callbacks:r.callbacks,head:r.head}}function C(e,t,r){return e==null||t==null?!1:e.nodeType===t.nodeType&&e.tagName===t.tagName?e.id!==""&&e.id===t.id?!0:M(r,e,t)>0:!1}function R(e,t){return e==null||t==null?!1:e.nodeType===t.nodeType&&e.tagName===t.tagName}function P(e,t,r){for(;e!==t;){let n=e;e=e.nextSibling,j(n,r)}return S(r,t),t.nextSibling}function Y(e,t,r,n,i){let l=M(i,r,t),s=null;if(l>0){let m=n,y=0;for(;m!=null;){if(C(r,m,i))return m;if(y+=M(i,m,e),y>l)return null;m=m.nextSibling}}return s}function G(e,t,r,n,i){let l=n,s=r.nextSibling,m=0;for(;l!=null;){if(M(i,l,e)>0)return null;if(R(r,l))return l;if(R(s,l)&&(m++,s=s.nextSibling,m>=2))return null;l=l.nextSibling}return l}function K(e){let t=new DOMParser,r=e.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");if(r.match(/<\/html>/)||r.match(/<\/head>/)||r.match(/<\/body>/)){let n=t.parseFromString(e,"text/html");if(r.match(/<\/html>/))return n.generatedByIdiomorph=!0,n;{let i=n.firstChild;return i?(i.generatedByIdiomorph=!0,i):null}}else{let i=t.parseFromString("<body><template>"+e+"</template></body>","text/html").body.querySelector("template").content;return i.generatedByIdiomorph=!0,i}}function Q(e){if(e==null)return document.createElement("div");if(e.generatedByIdiomorph)return e;if(e instanceof Node){let t=document.createElement("div");return t.append(e),t}else{let t=document.createElement("div");for(let r of[...e])t.append(r);return t}}function Z(e,t,r){let n=[],i=[];for(;e!=null;)n.push(e),e=e.previousSibling;for(;n.length>0;){let l=n.pop();i.push(l),t.parentElement.insertBefore(l,t)}for(i.push(t);r!=null;)n.push(r),i.push(r),r=r.nextSibling;for(;n.length>0;)t.parentElement.insertBefore(n.pop(),t.nextSibling);return i}function x(e,t,r){let n;n=e.firstChild;let i=n,l=0;for(;n;){let s=ee(n,t,r);s>l&&(i=n,l=s),n=n.nextSibling}return i}function ee(e,t,r){return R(e,t)?.5+M(r,e,t):0}function j(e,t){S(t,e),t.callbacks.beforeNodeRemoved(e)!==!1&&(e.remove(),t.callbacks.afterNodeRemoved(e))}function te(e,t){return!e.deadIds.has(t)}function re(e,t,r){return(e.idMap.get(r)||a).has(t)}function S(e,t){let r=e.idMap.get(t)||a;for(let n of r)e.deadIds.add(n)}function M(e,t,r){let n=e.idMap.get(t)||a,i=0;for(let l of n)te(e,l)&&re(e,l,r)&&++i;return i}function D(e,t){let r=e.parentElement,n=e.querySelectorAll("[id]");for(let i of n){let l=i;for(;l!==r&&l!=null;){let s=t.get(l);s==null&&(s=new Set,t.set(l,s)),s.add(i.id),l=l.parentElement}}}function ne(e,t){let r=new Map;return D(e,r),D(t,r),r}return{morph:u,defaults:o}}();var de=/INPUT/i,ce=/date|datetime-local|email|month|number|password|range|search|tel|text|time|url|week/i,he=/TEXTAREA/i,me=/TRIX-EDITOR/i,pe=a=>a.nodeType!==Node.ELEMENT_NODE||a!==document.activeElement?!0:a.hasAttribute(w.turboPermanentAttribute)&&a.getAttribute(w.turboPermanentAttribute)!=="false"||a.tagName.match(he)||a.tagName.match(me)?!1:a.tagName.match(de)&&a.getAttribute("type").match(ce),be={beforeNodeMorphed:(a,o)=>pe(a)},ve=(a,o)=>_.morph(a,o,{callbacks:be}),X=ve;var k={before:"turbo-boost:stream:before-invoke",after:"turbo-boost:stream:after-invoke",finish:"turbo-boost:stream:finish-invoke"};function O(a,o,u){let{object:p,target:d}=a;o=o||{},o=U(V({},o),{object:a.object});let f={detail:o,bubbles:!0};d.dispatchEvent(new CustomEvent(k.before,f));let{delay:b}=o.invoke||{};b=b||0;let c=()=>{let g=u(p);f.detail.result=g,d.dispatchEvent(new CustomEvent(k.after,f));let v;g instanceof Animation&&(v=g.finished),g instanceof Promise&&(v=g),v?v.then(()=>{f.detail.promise="fulfilled",d.dispatchEvent(new CustomEvent(k.finish,f))},()=>{f.detail.promise="rejected",d.dispatchEvent(new CustomEvent(k.finish,f))}):d.dispatchEvent(new CustomEvent(k.finish,f))};b>0?setTimeout(c,b):c()}function ge(a,o,u){let p=o[0],d=o[1],f={method:a,eventName:p,eventOptions:d};u.forEach(b=>O(b,f,c=>c.dispatchEvent(new CustomEvent(p,d))))}function Ee(a,o,u){let p=o[0],d={method:a,html:p};u.forEach(f=>O(f,d,b=>X(b,p)))}function Ae(a,o,u){let p=a.slice(0,-1).trim(),d=o[0],f={method:a,property:p,value:d};u.forEach(b=>O(b,f,c=>c[p]=d))}function Se(a,o,u){let p={method:a,args:o};u.forEach(d=>O(d,p,f=>f[a].apply(f,o)))}function $(a,o,u){return a.match(/^dispatch(Event)?$/)?ge(a,o,u):a.match(/^morph|mutate$/)?Ee(a,o,u):a.endsWith("=")?Ae(a,o,u):Se(a,o,u)}function B(){let a=JSON.parse(this.templateContent.textContent),{id:o,selector:u,receiver:p,method:d,args:f,delay:b}=a,c=[{object:self,target:self}];u&&(c=Array.from(document.querySelectorAll(u)).map(g=>({object:g,target:g}))),p&&(c=c.map(g=>{let{object:v,target:H}=g,T=p.split(".");for(;T.length>0;)v=v[T.shift()],v.dispatchEvent&&(H=v);return{object:v,target:H}})),b>0?setTimeout(()=>$(d,f,c),b):$(d,f,c)}if(!self.Turbo)throw new Error("`Turbo` is not defined! Be sure to import `@turbo-boost/streams` after `@hotwired/turbo` or `@hotwired/turbo-rails`.");if(!Turbo.StreamActions)throw new Error("`Turbo.StreamActions` is not defined! Verify that you are running >= `7.2.0` of `@hotwired/turbo`.");Turbo.StreamActions.invoke=B;self.TurboBoost=self.TurboBoost||{};self.TurboBoost.Streams={invoke:B,invokeEvents:k,schema:w,VERSION:W};console.info("@turbo-boost/streams has initialized and registered new stream actions with Turbo.");var De=self.TurboBoost.Streams;export{De as default};
1
+ var ue=Object.defineProperty,fe=Object.defineProperties;var de=Object.getOwnPropertyDescriptors;var W=Object.getOwnPropertySymbols;var ce=Object.prototype.hasOwnProperty,he=Object.prototype.propertyIsEnumerable;var $=(l,o,u)=>o in l?ue(l,o,{enumerable:!0,configurable:!0,writable:!0,value:u}):l[o]=u,y=(l,o)=>{for(var u in o||(o={}))ce.call(o,u)&&$(l,u,o[u]);if(W)for(var u of W(o))he.call(o,u)&&$(l,u,o[u]);return l},O=(l,o)=>fe(l,de(o));var z="0.1.11";var me={turboPermanentAttribute:"data-turbo-permanent"},R=y({},me);var J=function(){"use strict";let l=new Set,o={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:A,afterNodeAdded:A,beforeNodeMorphed:A,afterNodeMorphed:A,beforeNodeRemoved:A,afterNodeRemoved:A,beforeAttributeUpdated:A},head:{style:"merge",shouldPreserve:function(e){return e.getAttribute("im-preserve")==="true"},shouldReAppend:function(e){return e.getAttribute("im-re-append")==="true"},shouldRemove:A,afterHeadMorphed:A}};function u(e,t,r={}){e instanceof Document&&(e=e.documentElement),typeof t=="string"&&(t=ee(t));let n=te(t),i=Q(e,n,r);return c(e,n,i)}function c(e,t,r){if(r.head.block){let n=e.querySelector("head"),i=t.querySelector("head");if(n&&i){let a=I(i,n,r);Promise.all(a).then(function(){c(e,t,Object.assign(r,{head:{block:!1,ignore:!0}}))});return}}if(r.morphStyle==="innerHTML")return b(t,e,r),e.children;if(r.morphStyle==="outerHTML"||r.morphStyle==null){let n=ne(t,e,r),i=n==null?void 0:n.previousSibling,a=n==null?void 0:n.nextSibling,s=f(e,n,r);return n?re(i,s,a):[]}else throw"Do not understand how to morph style "+r.morphStyle}function d(e,t){return t.ignoreActiveValue&&e===document.activeElement&&e!==document.body}function f(e,t,r){if(!(r.ignoreActive&&e===document.activeElement))return t==null?r.callbacks.beforeNodeRemoved(e)===!1?e:(e.remove(),r.callbacks.afterNodeRemoved(e),null):V(e,t)?(r.callbacks.beforeNodeMorphed(e,t)===!1||(e instanceof HTMLHeadElement&&r.head.ignore||(e instanceof HTMLHeadElement&&r.head.style!=="morph"?I(t,e,r):(g(t,e,r),d(e,r)||b(t,e,r))),r.callbacks.afterNodeMorphed(e,t)),e):r.callbacks.beforeNodeRemoved(e)===!1||r.callbacks.beforeNodeAdded(t)===!1?e:(e.parentElement.replaceChild(t,e),r.callbacks.afterNodeAdded(t),r.callbacks.afterNodeRemoved(e),t)}function b(e,t,r){let n=e.firstChild,i=t.firstChild,a;for(;n;){if(a=n,n=a.nextSibling,i==null){if(r.callbacks.beforeNodeAdded(a)===!1)return;t.appendChild(a),r.callbacks.afterNodeAdded(a),S(r,a);continue}if(F(a,i,r)){f(i,a,r),i=i.nextSibling,S(r,a);continue}let s=Z(e,t,a,i,r);if(s){i=q(i,s,r),f(s,a,r),S(r,a);continue}let p=x(e,t,a,i,r);if(p){i=q(i,p,r),f(p,a,r),S(r,a);continue}if(r.callbacks.beforeNodeAdded(a)===!1)return;t.insertBefore(a,i),r.callbacks.afterNodeAdded(a),S(r,a)}for(;i!==null;){let s=i;i=i.nextSibling,_(s,r)}}function h(e,t,r,n){return e==="value"&&n.ignoreActiveValue&&t===document.activeElement?!0:n.callbacks.beforeAttributeUpdated(e,t,r)===!1}function g(e,t,r){let n=e.nodeType;if(n===1){let i=e.attributes,a=t.attributes;for(let s of i)h(s.name,t,"update",r)||t.getAttribute(s.name)!==s.value&&t.setAttribute(s.name,s.value);for(let s=a.length-1;0<=s;s--){let p=a[s];h(p.name,t,"remove",r)||e.hasAttribute(p.name)||t.removeAttribute(p.name)}}(n===8||n===3)&&t.nodeValue!==e.nodeValue&&(t.nodeValue=e.nodeValue),d(t,r)||T(e,t,r)}function v(e,t,r,n){if(e[r]!==t[r]){let i=h(r,t,"update",n);i||(t[r]=e[r]),e[r]?i||t.setAttribute(r,e[r]):h(r,t,"remove",n)||t.removeAttribute(r)}}function T(e,t,r){if(e instanceof HTMLInputElement&&t instanceof HTMLInputElement&&e.type!=="file"){let n=e.value,i=t.value;v(e,t,"checked",r),v(e,t,"disabled",r),e.hasAttribute("value")?n!==i&&(h("value",t,"update",r)||(t.setAttribute("value",n),t.value=n)):h("value",t,"remove",r)||(t.value="",t.removeAttribute("value"))}else if(e instanceof HTMLOptionElement)v(e,t,"selected",r);else if(e instanceof HTMLTextAreaElement&&t instanceof HTMLTextAreaElement){let n=e.value,i=t.value;if(h("value",t,"update",r))return;n!==i&&(t.value=n),t.firstChild&&t.firstChild.nodeValue!==n&&(t.firstChild.nodeValue=n)}}function I(e,t,r){let n=[],i=[],a=[],s=[],p=r.head.style,k=new Map;for(let m of e.children)k.set(m.outerHTML,m);for(let m of t.children){let E=k.has(m.outerHTML),H=r.head.shouldReAppend(m),C=r.head.shouldPreserve(m);E||C?H?i.push(m):(k.delete(m.outerHTML),a.push(m)):p==="append"?H&&(i.push(m),s.push(m)):r.head.shouldRemove(m)!==!1&&i.push(m)}s.push(...k.values());let U=[];for(let m of s){let E=document.createRange().createContextualFragment(m.outerHTML).firstChild;if(r.callbacks.beforeNodeAdded(E)!==!1){if(E.href||E.src){let H=null,C=new Promise(function(se){H=se});E.addEventListener("load",function(){H()}),U.push(C)}t.appendChild(E),r.callbacks.afterNodeAdded(E),n.push(E)}}for(let m of i)r.callbacks.beforeNodeRemoved(m)!==!1&&(t.removeChild(m),r.callbacks.afterNodeRemoved(m));return r.head.afterHeadMorphed(t,{added:n,kept:a,removed:i}),U}function Me(){}function A(){}function K(e){let t={};return Object.assign(t,o),Object.assign(t,e),t.callbacks={},Object.assign(t.callbacks,o.callbacks),Object.assign(t.callbacks,e.callbacks),t.head={},Object.assign(t.head,o.head),Object.assign(t.head,e.head),t}function Q(e,t,r){return r=K(r),{target:e,newContent:t,config:r,morphStyle:r.morphStyle,ignoreActive:r.ignoreActive,ignoreActiveValue:r.ignoreActiveValue,idMap:oe(e,t),deadIds:new Set,callbacks:r.callbacks,head:r.head}}function F(e,t,r){return e==null||t==null?!1:e.nodeType===t.nodeType&&e.tagName===t.tagName?e.id!==""&&e.id===t.id?!0:w(r,e,t)>0:!1}function V(e,t){return e==null||t==null?!1:e.nodeType===t.nodeType&&e.tagName===t.tagName}function q(e,t,r){for(;e!==t;){let n=e;e=e.nextSibling,_(n,r)}return S(r,t),t.nextSibling}function Z(e,t,r,n,i){let a=w(i,r,t),s=null;if(a>0){let p=n,k=0;for(;p!=null;){if(F(r,p,i))return p;if(k+=w(i,p,e),k>a)return null;p=p.nextSibling}}return s}function x(e,t,r,n,i){let a=n,s=r.nextSibling,p=0;for(;a!=null;){if(w(i,a,e)>0)return null;if(V(r,a))return a;if(V(s,a)&&(p++,s=s.nextSibling,p>=2))return null;a=a.nextSibling}return a}function ee(e){let t=new DOMParser,r=e.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");if(r.match(/<\/html>/)||r.match(/<\/head>/)||r.match(/<\/body>/)){let n=t.parseFromString(e,"text/html");if(r.match(/<\/html>/))return n.generatedByIdiomorph=!0,n;{let i=n.firstChild;return i?(i.generatedByIdiomorph=!0,i):null}}else{let i=t.parseFromString("<body><template>"+e+"</template></body>","text/html").body.querySelector("template").content;return i.generatedByIdiomorph=!0,i}}function te(e){if(e==null)return document.createElement("div");if(e.generatedByIdiomorph)return e;if(e instanceof Node){let t=document.createElement("div");return t.append(e),t}else{let t=document.createElement("div");for(let r of[...e])t.append(r);return t}}function re(e,t,r){let n=[],i=[];for(;e!=null;)n.push(e),e=e.previousSibling;for(;n.length>0;){let a=n.pop();i.push(a),t.parentElement.insertBefore(a,t)}for(i.push(t);r!=null;)n.push(r),i.push(r),r=r.nextSibling;for(;n.length>0;)t.parentElement.insertBefore(n.pop(),t.nextSibling);return i}function ne(e,t,r){let n;n=e.firstChild;let i=n,a=0;for(;n;){let s=ie(n,t,r);s>a&&(i=n,a=s),n=n.nextSibling}return i}function ie(e,t,r){return V(e,t)?.5+w(r,e,t):0}function _(e,t){S(t,e),t.callbacks.beforeNodeRemoved(e)!==!1&&(e.remove(),t.callbacks.afterNodeRemoved(e))}function le(e,t){return!e.deadIds.has(t)}function ae(e,t,r){return(e.idMap.get(r)||l).has(t)}function S(e,t){let r=e.idMap.get(t)||l;for(let n of r)e.deadIds.add(n)}function w(e,t,r){let n=e.idMap.get(t)||l,i=0;for(let a of n)le(e,a)&&ae(e,a,r)&&++i;return i}function N(e,t){let r=e.parentElement,n=e.querySelectorAll("[id]");for(let i of n){let a=i;for(;a!==r&&a!=null;){let s=t.get(a);s==null&&(s=new Set,t.set(a,s)),s.add(i.id),a=a.parentElement}}}function oe(e,t){let r=new Map;return N(e,r),N(t,r),r}return{morph:u,defaults:o}}();var P,j=0,pe=/TRIX-EDITOR/i;function Y(l){return l.nodeType===Node.ELEMENT_NODE}function be(l){return Y(l)?l.hasAttribute(R.turboPermanentAttribute)&&l.getAttribute(R.turboPermanentAttribute)!=="false":!1}function ve(l){return Y(l)?l===document.activeElement:!1}function ge(l){return!(be(l)||ve(l)&&l.tagName.match(pe))}var X={callbacks:{beforeNodeMorphed:(l,o)=>ge(l)},morphStyle:"outerHTML",ignoreActiveValue:!0,head:{style:"merge"}};function Ee(l,o,u={}){let c=y(y({},X.callbacks),u.callbacks);return u=O(y(y({},X),u),{callbacks:c}),new Promise(d=>{setTimeout(()=>{J.morph(l,o,u),d()},j)})}P=Ee;var L={get delay(){return j},set delay(l){j=l},get method(){return P},set method(l){P=l}};var M={before:"turbo-boost:stream:before-invoke",after:"turbo-boost:stream:after-invoke",finish:"turbo-boost:stream:finish-invoke"};function B(l,o,u){let{object:c,target:d}=l;o=o||{},o=O(y({},o),{object:l.object});let f={detail:o,bubbles:!0};d.dispatchEvent(new CustomEvent(M.before,f));let{delay:b}=o.invoke||{};b=b||0;let h=()=>{let g=u(c);f.detail.result=g,d.dispatchEvent(new CustomEvent(M.after,f));let v;g instanceof Animation&&(v=g.finished),g instanceof Promise&&(v=g),v?v.then(()=>{f.detail.promise="fulfilled",d.dispatchEvent(new CustomEvent(M.finish,f))}).catch(T=>{f.detail.promise="rejected",f.detail.error=T,d.dispatchEvent(new CustomEvent(M.finish,f))}):d.dispatchEvent(new CustomEvent(M.finish,f))};b>0?setTimeout(h,b):h()}function Ae(l,o,u){let c=o[0],d=o[1],f={method:l,eventName:c,eventOptions:d};u.forEach(b=>B(b,f,h=>h.dispatchEvent(new CustomEvent(c,d))))}function ye(l,o,u){let c=o[0],d={method:l,html:c};u.forEach(f=>B(f,d,b=>L.method(b,c)))}function Se(l,o,u){let c=l.slice(0,-1).trim(),d=o[0],f={method:l,property:c,value:d};u.forEach(b=>B(b,f,h=>h[c]=d))}function ke(l,o,u){let c={method:l,args:o};u.forEach(d=>B(d,c,f=>f[l].apply(f,o)))}function G(l,o,u){return l.match(/^dispatch(Event)?$/)?Ae(l,o,u):l.match(/^morph|mutate$/)?ye(l,o,u):l.endsWith("=")?Se(l,o,u):ke(l,o,u)}function D(){let l=JSON.parse(this.templateContent.textContent),{id:o,selector:u,receiver:c,method:d,args:f,delay:b}=l,h=[{object:self,target:self}];u&&(h=Array.from(document.querySelectorAll(u)).map(g=>({object:g,target:g}))),c&&(h=h.map(g=>{let{object:v,target:T}=g,I=c.split(".");for(;I.length>0;)v=v[I.shift()],v.dispatchEvent&&(T=v);return{object:v,target:T}})),b>0?setTimeout(()=>G(d,f,h),b):G(d,f,h)}if(!self.Turbo)throw new Error("`Turbo` is not defined! Be sure to import `@turbo-boost/streams` after `@hotwired/turbo` or `@hotwired/turbo-rails`.");if(!Turbo.StreamActions)throw new Error("`Turbo.StreamActions` is not defined! Verify that you are running >= `7.2.0` of `@hotwired/turbo`.");Turbo.StreamActions.invoke=D;self.TurboBoost=self.TurboBoost||{};self.TurboBoost.Streams={invoke:D,invokeEvents:M,morph:L,schema:R,VERSION:z};console.info("@turbo-boost/streams has initialized and registered new stream actions with Turbo.");var Ne=self.TurboBoost.Streams;export{Ne as default};
2
2
  //# sourceMappingURL=streams.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../javascript/version.js", "../../../javascript/schema.js", "../../../../node_modules/idiomorph/dist/idiomorph.esm.js", "../../../javascript/morph.js", "../../../javascript/invoke.js", "../../../javascript/index.js"],
4
- "sourcesContent": ["export default '0.1.10'\n", "const schema = {\n turboPermanentAttribute: 'data-turbo-permanent'\n}\n\nexport default { ...schema }\n", "// base IIFE to define idiomorph\nvar Idiomorph = (function () {\n 'use strict';\n\n //=============================================================================\n // AND NOW IT BEGINS...\n //=============================================================================\n let EMPTY_SET = new Set();\n\n // default configuration values, updatable by users now\n let defaults = {\n morphStyle: \"outerHTML\",\n callbacks : {\n beforeNodeAdded: noOp,\n afterNodeAdded: noOp,\n beforeNodeMorphed: noOp,\n afterNodeMorphed: noOp,\n beforeNodeRemoved: noOp,\n afterNodeRemoved: noOp,\n beforeAttributeUpdated: noOp,\n\n },\n head: {\n style: 'merge',\n shouldPreserve: function (elt) {\n return elt.getAttribute(\"im-preserve\") === \"true\";\n },\n shouldReAppend: function (elt) {\n return elt.getAttribute(\"im-re-append\") === \"true\";\n },\n shouldRemove: noOp,\n afterHeadMorphed: noOp,\n }\n };\n\n //=============================================================================\n // Core Morphing Algorithm - morph, morphNormalizedContent, morphOldNodeTo, morphChildren\n //=============================================================================\n function morph(oldNode, newContent, config = {}) {\n\n if (oldNode instanceof Document) {\n oldNode = oldNode.documentElement;\n }\n\n if (typeof newContent === 'string') {\n newContent = parseContent(newContent);\n }\n\n let normalizedContent = normalizeContent(newContent);\n\n let ctx = createMorphContext(oldNode, normalizedContent, config);\n\n return morphNormalizedContent(oldNode, normalizedContent, ctx);\n }\n\n function morphNormalizedContent(oldNode, normalizedNewContent, ctx) {\n if (ctx.head.block) {\n let oldHead = oldNode.querySelector('head');\n let newHead = normalizedNewContent.querySelector('head');\n if (oldHead && newHead) {\n let promises = handleHeadElement(newHead, oldHead, ctx);\n // when head promises resolve, call morph again, ignoring the head tag\n Promise.all(promises).then(function () {\n morphNormalizedContent(oldNode, normalizedNewContent, Object.assign(ctx, {\n head: {\n block: false,\n ignore: true\n }\n }));\n });\n return;\n }\n }\n\n if (ctx.morphStyle === \"innerHTML\") {\n\n // innerHTML, so we are only updating the children\n morphChildren(normalizedNewContent, oldNode, ctx);\n return oldNode.children;\n\n } else if (ctx.morphStyle === \"outerHTML\" || ctx.morphStyle == null) {\n // otherwise find the best element match in the new content, morph that, and merge its siblings\n // into either side of the best match\n let bestMatch = findBestNodeMatch(normalizedNewContent, oldNode, ctx);\n\n // stash the siblings that will need to be inserted on either side of the best match\n let previousSibling = bestMatch?.previousSibling;\n let nextSibling = bestMatch?.nextSibling;\n\n // morph it\n let morphedNode = morphOldNodeTo(oldNode, bestMatch, ctx);\n\n if (bestMatch) {\n // if there was a best match, merge the siblings in too and return the\n // whole bunch\n return insertSiblings(previousSibling, morphedNode, nextSibling);\n } else {\n // otherwise nothing was added to the DOM\n return []\n }\n } else {\n throw \"Do not understand how to morph style \" + ctx.morphStyle;\n }\n }\n\n\n /**\n * @param possibleActiveElement\n * @param ctx\n * @returns {boolean}\n */\n function ignoreValueOfActiveElement(possibleActiveElement, ctx) {\n return ctx.ignoreActiveValue && possibleActiveElement === document.activeElement && possibleActiveElement !== document.body;\n }\n\n /**\n * @param oldNode root node to merge content into\n * @param newContent new content to merge\n * @param ctx the merge context\n * @returns {Element} the element that ended up in the DOM\n */\n function morphOldNodeTo(oldNode, newContent, ctx) {\n if (ctx.ignoreActive && oldNode === document.activeElement) {\n // don't morph focused element\n } else if (newContent == null) {\n if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;\n\n oldNode.remove();\n ctx.callbacks.afterNodeRemoved(oldNode);\n return null;\n } else if (!isSoftMatch(oldNode, newContent)) {\n if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;\n if (ctx.callbacks.beforeNodeAdded(newContent) === false) return oldNode;\n\n oldNode.parentElement.replaceChild(newContent, oldNode);\n ctx.callbacks.afterNodeAdded(newContent);\n ctx.callbacks.afterNodeRemoved(oldNode);\n return newContent;\n } else {\n if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) return oldNode;\n\n if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) {\n // ignore the head element\n } else if (oldNode instanceof HTMLHeadElement && ctx.head.style !== \"morph\") {\n handleHeadElement(newContent, oldNode, ctx);\n } else {\n syncNodeFrom(newContent, oldNode, ctx);\n if (!ignoreValueOfActiveElement(oldNode, ctx)) {\n morphChildren(newContent, oldNode, ctx);\n }\n }\n ctx.callbacks.afterNodeMorphed(oldNode, newContent);\n return oldNode;\n }\n }\n\n /**\n * This is the core algorithm for matching up children. The idea is to use id sets to try to match up\n * nodes as faithfully as possible. We greedily match, which allows us to keep the algorithm fast, but\n * by using id sets, we are able to better match up with content deeper in the DOM.\n *\n * Basic algorithm is, for each node in the new content:\n *\n * - if we have reached the end of the old parent, append the new content\n * - if the new content has an id set match with the current insertion point, morph\n * - search for an id set match\n * - if id set match found, morph\n * - otherwise search for a \"soft\" match\n * - if a soft match is found, morph\n * - otherwise, prepend the new node before the current insertion point\n *\n * The two search algorithms terminate if competing node matches appear to outweigh what can be achieved\n * with the current node. See findIdSetMatch() and findSoftMatch() for details.\n *\n * @param {Element} newParent the parent element of the new content\n * @param {Element } oldParent the old content that we are merging the new content into\n * @param ctx the merge context\n */\n function morphChildren(newParent, oldParent, ctx) {\n\n let nextNewChild = newParent.firstChild;\n let insertionPoint = oldParent.firstChild;\n let newChild;\n\n // run through all the new content\n while (nextNewChild) {\n\n newChild = nextNewChild;\n nextNewChild = newChild.nextSibling;\n\n // if we are at the end of the exiting parent's children, just append\n if (insertionPoint == null) {\n if (ctx.callbacks.beforeNodeAdded(newChild) === false) return;\n\n oldParent.appendChild(newChild);\n ctx.callbacks.afterNodeAdded(newChild);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // if the current node has an id set match then morph\n if (isIdSetMatch(newChild, insertionPoint, ctx)) {\n morphOldNodeTo(insertionPoint, newChild, ctx);\n insertionPoint = insertionPoint.nextSibling;\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // otherwise search forward in the existing old children for an id set match\n let idSetMatch = findIdSetMatch(newParent, oldParent, newChild, insertionPoint, ctx);\n\n // if we found a potential match, remove the nodes until that point and morph\n if (idSetMatch) {\n insertionPoint = removeNodesBetween(insertionPoint, idSetMatch, ctx);\n morphOldNodeTo(idSetMatch, newChild, ctx);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // no id set match found, so scan forward for a soft match for the current node\n let softMatch = findSoftMatch(newParent, oldParent, newChild, insertionPoint, ctx);\n\n // if we found a soft match for the current node, morph\n if (softMatch) {\n insertionPoint = removeNodesBetween(insertionPoint, softMatch, ctx);\n morphOldNodeTo(softMatch, newChild, ctx);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // abandon all hope of morphing, just insert the new child before the insertion point\n // and move on\n if (ctx.callbacks.beforeNodeAdded(newChild) === false) return;\n\n oldParent.insertBefore(newChild, insertionPoint);\n ctx.callbacks.afterNodeAdded(newChild);\n removeIdsFromConsideration(ctx, newChild);\n }\n\n // remove any remaining old nodes that didn't match up with new content\n while (insertionPoint !== null) {\n\n let tempNode = insertionPoint;\n insertionPoint = insertionPoint.nextSibling;\n removeNode(tempNode, ctx);\n }\n }\n\n //=============================================================================\n // Attribute Syncing Code\n //=============================================================================\n\n /**\n * @param attr {String} the attribute to be mutated\n * @param to {Element} the element that is going to be updated\n * @param updateType {(\"update\"|\"remove\")}\n * @param ctx the merge context\n * @returns {boolean} true if the attribute should be ignored, false otherwise\n */\n function ignoreAttribute(attr, to, updateType, ctx) {\n if(attr === 'value' && ctx.ignoreActiveValue && to === document.activeElement){\n return true;\n }\n return ctx.callbacks.beforeAttributeUpdated(attr, to, updateType) === false;\n }\n\n /**\n * syncs a given node with another node, copying over all attributes and\n * inner element state from the 'from' node to the 'to' node\n *\n * @param {Element} from the element to copy attributes & state from\n * @param {Element} to the element to copy attributes & state to\n * @param ctx the merge context\n */\n function syncNodeFrom(from, to, ctx) {\n let type = from.nodeType\n\n // if is an element type, sync the attributes from the\n // new node into the new node\n if (type === 1 /* element type */) {\n const fromAttributes = from.attributes;\n const toAttributes = to.attributes;\n for (const fromAttribute of fromAttributes) {\n if (ignoreAttribute(fromAttribute.name, to, 'update', ctx)) {\n continue;\n }\n if (to.getAttribute(fromAttribute.name) !== fromAttribute.value) {\n to.setAttribute(fromAttribute.name, fromAttribute.value);\n }\n }\n // iterate backwards to avoid skipping over items when a delete occurs\n for (let i = toAttributes.length - 1; 0 <= i; i--) {\n const toAttribute = toAttributes[i];\n if (ignoreAttribute(toAttribute.name, to, 'remove', ctx)) {\n continue;\n }\n if (!from.hasAttribute(toAttribute.name)) {\n to.removeAttribute(toAttribute.name);\n }\n }\n }\n\n // sync text nodes\n if (type === 8 /* comment */ || type === 3 /* text */) {\n if (to.nodeValue !== from.nodeValue) {\n to.nodeValue = from.nodeValue;\n }\n }\n\n if (!ignoreValueOfActiveElement(to, ctx)) {\n // sync input values\n syncInputValue(from, to, ctx);\n }\n }\n\n /**\n * @param from {Element} element to sync the value from\n * @param to {Element} element to sync the value to\n * @param attributeName {String} the attribute name\n * @param ctx the merge context\n */\n function syncBooleanAttribute(from, to, attributeName, ctx) {\n if (from[attributeName] !== to[attributeName]) {\n let ignoreUpdate = ignoreAttribute(attributeName, to, 'update', ctx);\n if (!ignoreUpdate) {\n to[attributeName] = from[attributeName];\n }\n if (from[attributeName]) {\n if (!ignoreUpdate) {\n to.setAttribute(attributeName, from[attributeName]);\n }\n } else {\n if (!ignoreAttribute(attributeName, to, 'remove', ctx)) {\n to.removeAttribute(attributeName);\n }\n }\n }\n }\n\n /**\n * NB: many bothans died to bring us information:\n *\n * https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n * https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113\n *\n * @param from {Element} the element to sync the input value from\n * @param to {Element} the element to sync the input value to\n * @param ctx the merge context\n */\n function syncInputValue(from, to, ctx) {\n if (from instanceof HTMLInputElement &&\n to instanceof HTMLInputElement &&\n from.type !== 'file') {\n\n let fromValue = from.value;\n let toValue = to.value;\n\n // sync boolean attributes\n syncBooleanAttribute(from, to, 'checked', ctx);\n syncBooleanAttribute(from, to, 'disabled', ctx);\n\n if (!from.hasAttribute('value')) {\n if (!ignoreAttribute('value', to, 'remove', ctx)) {\n to.value = '';\n to.removeAttribute('value');\n }\n } else if (fromValue !== toValue) {\n if (!ignoreAttribute('value', to, 'update', ctx)) {\n to.setAttribute('value', fromValue);\n to.value = fromValue;\n }\n }\n } else if (from instanceof HTMLOptionElement) {\n syncBooleanAttribute(from, to, 'selected', ctx)\n } else if (from instanceof HTMLTextAreaElement && to instanceof HTMLTextAreaElement) {\n let fromValue = from.value;\n let toValue = to.value;\n if (ignoreAttribute('value', to, 'update', ctx)) {\n return;\n }\n if (fromValue !== toValue) {\n to.value = fromValue;\n }\n if (to.firstChild && to.firstChild.nodeValue !== fromValue) {\n to.firstChild.nodeValue = fromValue\n }\n }\n }\n\n //=============================================================================\n // the HEAD tag can be handled specially, either w/ a 'merge' or 'append' style\n //=============================================================================\n function handleHeadElement(newHeadTag, currentHead, ctx) {\n\n let added = []\n let removed = []\n let preserved = []\n let nodesToAppend = []\n\n let headMergeStyle = ctx.head.style;\n\n // put all new head elements into a Map, by their outerHTML\n let srcToNewHeadNodes = new Map();\n for (const newHeadChild of newHeadTag.children) {\n srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);\n }\n\n // for each elt in the current head\n for (const currentHeadElt of currentHead.children) {\n\n // If the current head element is in the map\n let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);\n let isReAppended = ctx.head.shouldReAppend(currentHeadElt);\n let isPreserved = ctx.head.shouldPreserve(currentHeadElt);\n if (inNewContent || isPreserved) {\n if (isReAppended) {\n // remove the current version and let the new version replace it and re-execute\n removed.push(currentHeadElt);\n } else {\n // this element already exists and should not be re-appended, so remove it from\n // the new content map, preserving it in the DOM\n srcToNewHeadNodes.delete(currentHeadElt.outerHTML);\n preserved.push(currentHeadElt);\n }\n } else {\n if (headMergeStyle === \"append\") {\n // we are appending and this existing element is not new content\n // so if and only if it is marked for re-append do we do anything\n if (isReAppended) {\n removed.push(currentHeadElt);\n nodesToAppend.push(currentHeadElt);\n }\n } else {\n // if this is a merge, we remove this content since it is not in the new head\n if (ctx.head.shouldRemove(currentHeadElt) !== false) {\n removed.push(currentHeadElt);\n }\n }\n }\n }\n\n // Push the remaining new head elements in the Map into the\n // nodes to append to the head tag\n nodesToAppend.push(...srcToNewHeadNodes.values());\n log(\"to append: \", nodesToAppend);\n\n let promises = [];\n for (const newNode of nodesToAppend) {\n log(\"adding: \", newNode);\n let newElt = document.createRange().createContextualFragment(newNode.outerHTML).firstChild;\n log(newElt);\n if (ctx.callbacks.beforeNodeAdded(newElt) !== false) {\n if (newElt.href || newElt.src) {\n let resolve = null;\n let promise = new Promise(function (_resolve) {\n resolve = _resolve;\n });\n newElt.addEventListener('load', function () {\n resolve();\n });\n promises.push(promise);\n }\n currentHead.appendChild(newElt);\n ctx.callbacks.afterNodeAdded(newElt);\n added.push(newElt);\n }\n }\n\n // remove all removed elements, after we have appended the new elements to avoid\n // additional network requests for things like style sheets\n for (const removedElement of removed) {\n if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {\n currentHead.removeChild(removedElement);\n ctx.callbacks.afterNodeRemoved(removedElement);\n }\n }\n\n ctx.head.afterHeadMorphed(currentHead, {added: added, kept: preserved, removed: removed});\n return promises;\n }\n\n //=============================================================================\n // Misc\n //=============================================================================\n\n function log() {\n //console.log(arguments);\n }\n\n function noOp() {\n }\n\n /*\n Deep merges the config object and the Idiomoroph.defaults object to\n produce a final configuration object\n */\n function mergeDefaults(config) {\n let finalConfig = {};\n // copy top level stuff into final config\n Object.assign(finalConfig, defaults);\n Object.assign(finalConfig, config);\n\n // copy callbacks into final config (do this to deep merge the callbacks)\n finalConfig.callbacks = {};\n Object.assign(finalConfig.callbacks, defaults.callbacks);\n Object.assign(finalConfig.callbacks, config.callbacks);\n\n // copy head config into final config (do this to deep merge the head)\n finalConfig.head = {};\n Object.assign(finalConfig.head, defaults.head);\n Object.assign(finalConfig.head, config.head);\n return finalConfig;\n }\n\n function createMorphContext(oldNode, newContent, config) {\n config = mergeDefaults(config);\n return {\n target: oldNode,\n newContent: newContent,\n config: config,\n morphStyle: config.morphStyle,\n ignoreActive: config.ignoreActive,\n ignoreActiveValue: config.ignoreActiveValue,\n idMap: createIdMap(oldNode, newContent),\n deadIds: new Set(),\n callbacks: config.callbacks,\n head: config.head\n }\n }\n\n function isIdSetMatch(node1, node2, ctx) {\n if (node1 == null || node2 == null) {\n return false;\n }\n if (node1.nodeType === node2.nodeType && node1.tagName === node2.tagName) {\n if (node1.id !== \"\" && node1.id === node2.id) {\n return true;\n } else {\n return getIdIntersectionCount(ctx, node1, node2) > 0;\n }\n }\n return false;\n }\n\n function isSoftMatch(node1, node2) {\n if (node1 == null || node2 == null) {\n return false;\n }\n return node1.nodeType === node2.nodeType && node1.tagName === node2.tagName\n }\n\n function removeNodesBetween(startInclusive, endExclusive, ctx) {\n while (startInclusive !== endExclusive) {\n let tempNode = startInclusive;\n startInclusive = startInclusive.nextSibling;\n removeNode(tempNode, ctx);\n }\n removeIdsFromConsideration(ctx, endExclusive);\n return endExclusive.nextSibling;\n }\n\n //=============================================================================\n // Scans forward from the insertionPoint in the old parent looking for a potential id match\n // for the newChild. We stop if we find a potential id match for the new child OR\n // if the number of potential id matches we are discarding is greater than the\n // potential id matches for the new child\n //=============================================================================\n function findIdSetMatch(newContent, oldParent, newChild, insertionPoint, ctx) {\n\n // max id matches we are willing to discard in our search\n let newChildPotentialIdCount = getIdIntersectionCount(ctx, newChild, oldParent);\n\n let potentialMatch = null;\n\n // only search forward if there is a possibility of an id match\n if (newChildPotentialIdCount > 0) {\n let potentialMatch = insertionPoint;\n // if there is a possibility of an id match, scan forward\n // keep track of the potential id match count we are discarding (the\n // newChildPotentialIdCount must be greater than this to make it likely\n // worth it)\n let otherMatchCount = 0;\n while (potentialMatch != null) {\n\n // If we have an id match, return the current potential match\n if (isIdSetMatch(newChild, potentialMatch, ctx)) {\n return potentialMatch;\n }\n\n // computer the other potential matches of this new content\n otherMatchCount += getIdIntersectionCount(ctx, potentialMatch, newContent);\n if (otherMatchCount > newChildPotentialIdCount) {\n // if we have more potential id matches in _other_ content, we\n // do not have a good candidate for an id match, so return null\n return null;\n }\n\n // advanced to the next old content child\n potentialMatch = potentialMatch.nextSibling;\n }\n }\n return potentialMatch;\n }\n\n //=============================================================================\n // Scans forward from the insertionPoint in the old parent looking for a potential soft match\n // for the newChild. We stop if we find a potential soft match for the new child OR\n // if we find a potential id match in the old parents children OR if we find two\n // potential soft matches for the next two pieces of new content\n //=============================================================================\n function findSoftMatch(newContent, oldParent, newChild, insertionPoint, ctx) {\n\n let potentialSoftMatch = insertionPoint;\n let nextSibling = newChild.nextSibling;\n let siblingSoftMatchCount = 0;\n\n while (potentialSoftMatch != null) {\n\n if (getIdIntersectionCount(ctx, potentialSoftMatch, newContent) > 0) {\n // the current potential soft match has a potential id set match with the remaining new\n // content so bail out of looking\n return null;\n }\n\n // if we have a soft match with the current node, return it\n if (isSoftMatch(newChild, potentialSoftMatch)) {\n return potentialSoftMatch;\n }\n\n if (isSoftMatch(nextSibling, potentialSoftMatch)) {\n // the next new node has a soft match with this node, so\n // increment the count of future soft matches\n siblingSoftMatchCount++;\n nextSibling = nextSibling.nextSibling;\n\n // If there are two future soft matches, bail to allow the siblings to soft match\n // so that we don't consume future soft matches for the sake of the current node\n if (siblingSoftMatchCount >= 2) {\n return null;\n }\n }\n\n // advanced to the next old content child\n potentialSoftMatch = potentialSoftMatch.nextSibling;\n }\n\n return potentialSoftMatch;\n }\n\n function parseContent(newContent) {\n let parser = new DOMParser();\n\n // remove svgs to avoid false-positive matches on head, etc.\n let contentWithSvgsRemoved = newContent.replace(/<svg(\\s[^>]*>|>)([\\s\\S]*?)<\\/svg>/gim, '');\n\n // if the newContent contains a html, head or body tag, we can simply parse it w/o wrapping\n if (contentWithSvgsRemoved.match(/<\\/html>/) || contentWithSvgsRemoved.match(/<\\/head>/) || contentWithSvgsRemoved.match(/<\\/body>/)) {\n let content = parser.parseFromString(newContent, \"text/html\");\n // if it is a full HTML document, return the document itself as the parent container\n if (contentWithSvgsRemoved.match(/<\\/html>/)) {\n content.generatedByIdiomorph = true;\n return content;\n } else {\n // otherwise return the html element as the parent container\n let htmlElement = content.firstChild;\n if (htmlElement) {\n htmlElement.generatedByIdiomorph = true;\n return htmlElement;\n } else {\n return null;\n }\n }\n } else {\n // if it is partial HTML, wrap it in a template tag to provide a parent element and also to help\n // deal with touchy tags like tr, tbody, etc.\n let responseDoc = parser.parseFromString(\"<body><template>\" + newContent + \"</template></body>\", \"text/html\");\n let content = responseDoc.body.querySelector('template').content;\n content.generatedByIdiomorph = true;\n return content\n }\n }\n\n function normalizeContent(newContent) {\n if (newContent == null) {\n // noinspection UnnecessaryLocalVariableJS\n const dummyParent = document.createElement('div');\n return dummyParent;\n } else if (newContent.generatedByIdiomorph) {\n // the template tag created by idiomorph parsing can serve as a dummy parent\n return newContent;\n } else if (newContent instanceof Node) {\n // a single node is added as a child to a dummy parent\n const dummyParent = document.createElement('div');\n dummyParent.append(newContent);\n return dummyParent;\n } else {\n // all nodes in the array or HTMLElement collection are consolidated under\n // a single dummy parent element\n const dummyParent = document.createElement('div');\n for (const elt of [...newContent]) {\n dummyParent.append(elt);\n }\n return dummyParent;\n }\n }\n\n function insertSiblings(previousSibling, morphedNode, nextSibling) {\n let stack = []\n let added = []\n while (previousSibling != null) {\n stack.push(previousSibling);\n previousSibling = previousSibling.previousSibling;\n }\n while (stack.length > 0) {\n let node = stack.pop();\n added.push(node); // push added preceding siblings on in order and insert\n morphedNode.parentElement.insertBefore(node, morphedNode);\n }\n added.push(morphedNode);\n while (nextSibling != null) {\n stack.push(nextSibling);\n added.push(nextSibling); // here we are going in order, so push on as we scan, rather than add\n nextSibling = nextSibling.nextSibling;\n }\n while (stack.length > 0) {\n morphedNode.parentElement.insertBefore(stack.pop(), morphedNode.nextSibling);\n }\n return added;\n }\n\n function findBestNodeMatch(newContent, oldNode, ctx) {\n let currentElement;\n currentElement = newContent.firstChild;\n let bestElement = currentElement;\n let score = 0;\n while (currentElement) {\n let newScore = scoreElement(currentElement, oldNode, ctx);\n if (newScore > score) {\n bestElement = currentElement;\n score = newScore;\n }\n currentElement = currentElement.nextSibling;\n }\n return bestElement;\n }\n\n function scoreElement(node1, node2, ctx) {\n if (isSoftMatch(node1, node2)) {\n return .5 + getIdIntersectionCount(ctx, node1, node2);\n }\n return 0;\n }\n\n function removeNode(tempNode, ctx) {\n removeIdsFromConsideration(ctx, tempNode)\n if (ctx.callbacks.beforeNodeRemoved(tempNode) === false) return;\n\n tempNode.remove();\n ctx.callbacks.afterNodeRemoved(tempNode);\n }\n\n //=============================================================================\n // ID Set Functions\n //=============================================================================\n\n function isIdInConsideration(ctx, id) {\n return !ctx.deadIds.has(id);\n }\n\n function idIsWithinNode(ctx, id, targetNode) {\n let idSet = ctx.idMap.get(targetNode) || EMPTY_SET;\n return idSet.has(id);\n }\n\n function removeIdsFromConsideration(ctx, node) {\n let idSet = ctx.idMap.get(node) || EMPTY_SET;\n for (const id of idSet) {\n ctx.deadIds.add(id);\n }\n }\n\n function getIdIntersectionCount(ctx, node1, node2) {\n let sourceSet = ctx.idMap.get(node1) || EMPTY_SET;\n let matchCount = 0;\n for (const id of sourceSet) {\n // a potential match is an id in the source and potentialIdsSet, but\n // that has not already been merged into the DOM\n if (isIdInConsideration(ctx, id) && idIsWithinNode(ctx, id, node2)) {\n ++matchCount;\n }\n }\n return matchCount;\n }\n\n /**\n * A bottom up algorithm that finds all elements with ids inside of the node\n * argument and populates id sets for those nodes and all their parents, generating\n * a set of ids contained within all nodes for the entire hierarchy in the DOM\n *\n * @param node {Element}\n * @param {Map<Node, Set<String>>} idMap\n */\n function populateIdMapForNode(node, idMap) {\n let nodeParent = node.parentElement;\n // find all elements with an id property\n let idElements = node.querySelectorAll('[id]');\n for (const elt of idElements) {\n let current = elt;\n // walk up the parent hierarchy of that element, adding the id\n // of element to the parent's id set\n while (current !== nodeParent && current != null) {\n let idSet = idMap.get(current);\n // if the id set doesn't exist, create it and insert it in the map\n if (idSet == null) {\n idSet = new Set();\n idMap.set(current, idSet);\n }\n idSet.add(elt.id);\n current = current.parentElement;\n }\n }\n }\n\n /**\n * This function computes a map of nodes to all ids contained within that node (inclusive of the\n * node). This map can be used to ask if two nodes have intersecting sets of ids, which allows\n * for a looser definition of \"matching\" than tradition id matching, and allows child nodes\n * to contribute to a parent nodes matching.\n *\n * @param {Element} oldContent the old content that will be morphed\n * @param {Element} newContent the new content to morph to\n * @returns {Map<Node, Set<String>>} a map of nodes to id sets for the\n */\n function createIdMap(oldContent, newContent) {\n let idMap = new Map();\n populateIdMapForNode(oldContent, idMap);\n populateIdMapForNode(newContent, idMap);\n return idMap;\n }\n\n //=============================================================================\n // This is what ends up becoming the Idiomorph global object\n //=============================================================================\n return {\n morph,\n defaults\n }\n })();\n\nexport {Idiomorph};\n", "import { Idiomorph } from 'idiomorph'\nimport schema from './schema'\n\nconst input = /INPUT/i\nconst inputTypes = /date|datetime-local|email|month|number|password|range|search|tel|text|time|url|week/i\nconst textarea = /TEXTAREA/i\nconst trixEditor = /TRIX-EDITOR/i\n\nconst morphAllowed = node => {\n if (node.nodeType !== Node.ELEMENT_NODE) return true\n if (node !== document.activeElement) return true\n\n // don't morph elements marked as turbo permanent\n if (\n node.hasAttribute(schema.turboPermanentAttribute) &&\n node.getAttribute(schema.turboPermanentAttribute) !== 'false'\n )\n return false\n\n // don't morph active textarea\n if (node.tagName.match(textarea)) return false\n\n // don't morph active trix-editor\n if (node.tagName.match(trixEditor)) return false\n\n // don't morph active inputs\n return node.tagName.match(input) && node.getAttribute('type').match(inputTypes)\n}\n\nconst callbacks = {\n beforeNodeMorphed: (oldNode, _newNode) => morphAllowed(oldNode)\n}\n\nconst morph = (element, html) => Idiomorph.morph(element, html, { callbacks })\n\nexport default morph\n", "import morph from './morph'\n\nexport const invokeEvents = {\n before: 'turbo-boost:stream:before-invoke',\n after: 'turbo-boost:stream:after-invoke',\n finish: 'turbo-boost:stream:finish-invoke'\n}\n\n// Invokes the callback on a single receiver with before/after events\nfunction withInvokeEvents(receiver, detail, callback) {\n const { object, target } = receiver\n detail = detail || {}\n detail = { ...detail, object: receiver.object }\n const options = { detail, bubbles: true }\n\n target.dispatchEvent(new CustomEvent(invokeEvents.before, options))\n\n // the before event can provide invoke instructions my modifying the event detail\n // For example, { delay: 1000 } will delay the invocation by 1000ms\n let { delay } = detail.invoke || {}\n delay = delay || 0\n\n const execute = () => {\n const result = callback(object)\n options.detail.result = result\n target.dispatchEvent(new CustomEvent(invokeEvents.after, options))\n\n let promise\n if (result instanceof Animation) promise = result.finished\n if (result instanceof Promise) promise = result\n\n if (promise)\n promise.then(\n () => {\n options.detail.promise = 'fulfilled'\n target.dispatchEvent(new CustomEvent(invokeEvents.finish, options))\n },\n () => {\n options.detail.promise = 'rejected'\n target.dispatchEvent(new CustomEvent(invokeEvents.finish, options))\n }\n )\n else target.dispatchEvent(new CustomEvent(invokeEvents.finish, options))\n }\n\n if (delay > 0) setTimeout(execute, delay)\n else execute()\n}\n\nfunction invokeDispatchEvent(method, args, receivers) {\n const eventName = args[0]\n const eventOptions = args[1]\n const detail = { method, eventName, eventOptions }\n receivers.forEach(receiver =>\n withInvokeEvents(receiver, detail, object =>\n object.dispatchEvent(new CustomEvent(eventName, eventOptions))\n )\n )\n}\n\nfunction invokeMorph(method, args, receivers) {\n const html = args[0]\n const detail = { method, html }\n receivers.forEach(receiver => withInvokeEvents(receiver, detail, object => morph(object, html)))\n}\n\nfunction invokeAssignment(method, args, receivers) {\n const property = method.slice(0, -1).trim()\n const value = args[0]\n const detail = { method, property, value }\n receivers.forEach(receiver => withInvokeEvents(receiver, detail, object => (object[property] = value)))\n}\n\nfunction invokeMethod(method, args, receivers) {\n const detail = { method, args }\n receivers.forEach(receiver =>\n withInvokeEvents(receiver, detail, object => object[method].apply(object, args))\n )\n}\n\n// Performs an invocation on all receivers for the given method and args\nfunction performInvoke(method, args, receivers) {\n // dispatch ................................................................................................\n if (method.match(/^dispatch(Event)?$/)) return invokeDispatchEvent(method, args, receivers)\n\n // morph ...................................................................................................\n if (method.match(/^morph|mutate$/)) return invokeMorph(method, args, receivers)\n\n // assignment ..............................................................................................\n if (method.endsWith('=')) return invokeAssignment(method, args, receivers)\n\n // method ..................................................................................................\n return invokeMethod(method, args, receivers)\n}\n\nexport function invoke() {\n const payload = JSON.parse(this.templateContent.textContent)\n const { id, selector, receiver, method, args, delay } = payload\n let receivers = [{ object: self, target: self }]\n if (selector)\n receivers = Array.from(document.querySelectorAll(selector)).map(el => ({\n object: el,\n target: el\n }))\n\n if (receiver) {\n receivers = receivers.map(r => {\n let { object, target } = r\n const chain = receiver.split('.')\n while (chain.length > 0) {\n object = object[chain.shift()]\n if (object.dispatchEvent) target = object\n }\n return { object, target }\n })\n }\n\n if (delay > 0) setTimeout(() => performInvoke(method, args, receivers), delay)\n else performInvoke(method, args, receivers)\n}\n", "import VERSION from './version'\nimport schema from './schema'\nimport { invoke, invokeEvents } from './invoke'\n\nif (!self['Turbo'])\n throw new Error(\n '`Turbo` is not defined! Be sure to import `@turbo-boost/streams` after `@hotwired/turbo` or `@hotwired/turbo-rails`.'\n )\n\nif (!Turbo['StreamActions'])\n throw new Error(\n '`Turbo.StreamActions` is not defined! Verify that you are running >= `7.2.0` of `@hotwired/turbo`.'\n )\n\nTurbo.StreamActions.invoke = invoke\nself.TurboBoost = self.TurboBoost || {}\nself.TurboBoost.Streams = { invoke, invokeEvents, schema, VERSION }\n\nconsole.info('@turbo-boost/streams has initialized and registered new stream actions with Turbo.')\n\nexport default self.TurboBoost.Streams\n"],
5
- "mappings": "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",
6
- "names": ["version_default", "schema", "schema_default", "__spreadValues", "Idiomorph", "EMPTY_SET", "defaults", "noOp", "elt", "morph", "oldNode", "newContent", "config", "parseContent", "normalizedContent", "normalizeContent", "ctx", "createMorphContext", "morphNormalizedContent", "normalizedNewContent", "oldHead", "newHead", "promises", "handleHeadElement", "morphChildren", "bestMatch", "findBestNodeMatch", "previousSibling", "nextSibling", "morphedNode", "morphOldNodeTo", "insertSiblings", "ignoreValueOfActiveElement", "possibleActiveElement", "isSoftMatch", "syncNodeFrom", "newParent", "oldParent", "nextNewChild", "insertionPoint", "newChild", "removeIdsFromConsideration", "isIdSetMatch", "idSetMatch", "findIdSetMatch", "removeNodesBetween", "softMatch", "findSoftMatch", "tempNode", "removeNode", "ignoreAttribute", "attr", "to", "updateType", "from", "type", "fromAttributes", "toAttributes", "fromAttribute", "i", "toAttribute", "syncInputValue", "syncBooleanAttribute", "attributeName", "ignoreUpdate", "fromValue", "toValue", "newHeadTag", "currentHead", "added", "removed", "preserved", "nodesToAppend", "headMergeStyle", "srcToNewHeadNodes", "newHeadChild", "currentHeadElt", "inNewContent", "isReAppended", "isPreserved", "newNode", "newElt", "resolve", "promise", "_resolve", "removedElement", "log", "mergeDefaults", "finalConfig", "createIdMap", "node1", "node2", "getIdIntersectionCount", "startInclusive", "endExclusive", "newChildPotentialIdCount", "potentialMatch", "otherMatchCount", "potentialSoftMatch", "siblingSoftMatchCount", "parser", "contentWithSvgsRemoved", "content", "htmlElement", "dummyParent", "stack", "node", "currentElement", "bestElement", "score", "newScore", "scoreElement", "isIdInConsideration", "id", "idIsWithinNode", "targetNode", "idSet", "sourceSet", "matchCount", "populateIdMapForNode", "idMap", "nodeParent", "idElements", "current", "oldContent", "input", "inputTypes", "textarea", "trixEditor", "morphAllowed", "node", "schema_default", "callbacks", "oldNode", "_newNode", "morph", "element", "html", "Idiomorph", "morph_default", "invokeEvents", "withInvokeEvents", "receiver", "detail", "callback", "object", "target", "__spreadProps", "__spreadValues", "options", "delay", "execute", "result", "promise", "invokeDispatchEvent", "method", "args", "receivers", "eventName", "eventOptions", "invokeMorph", "html", "morph_default", "invokeAssignment", "property", "value", "invokeMethod", "performInvoke", "invoke", "payload", "id", "selector", "el", "r", "chain", "invoke", "invokeEvents", "schema_default", "version_default", "javascript_default"]
4
+ "sourcesContent": ["export default '0.1.11'\n", "const schema = {\n turboPermanentAttribute: 'data-turbo-permanent'\n}\n\nexport default { ...schema }\n", "// base IIFE to define idiomorph\nvar Idiomorph = (function () {\n 'use strict';\n\n //=============================================================================\n // AND NOW IT BEGINS...\n //=============================================================================\n let EMPTY_SET = new Set();\n\n // default configuration values, updatable by users now\n let defaults = {\n morphStyle: \"outerHTML\",\n callbacks : {\n beforeNodeAdded: noOp,\n afterNodeAdded: noOp,\n beforeNodeMorphed: noOp,\n afterNodeMorphed: noOp,\n beforeNodeRemoved: noOp,\n afterNodeRemoved: noOp,\n beforeAttributeUpdated: noOp,\n\n },\n head: {\n style: 'merge',\n shouldPreserve: function (elt) {\n return elt.getAttribute(\"im-preserve\") === \"true\";\n },\n shouldReAppend: function (elt) {\n return elt.getAttribute(\"im-re-append\") === \"true\";\n },\n shouldRemove: noOp,\n afterHeadMorphed: noOp,\n }\n };\n\n //=============================================================================\n // Core Morphing Algorithm - morph, morphNormalizedContent, morphOldNodeTo, morphChildren\n //=============================================================================\n function morph(oldNode, newContent, config = {}) {\n\n if (oldNode instanceof Document) {\n oldNode = oldNode.documentElement;\n }\n\n if (typeof newContent === 'string') {\n newContent = parseContent(newContent);\n }\n\n let normalizedContent = normalizeContent(newContent);\n\n let ctx = createMorphContext(oldNode, normalizedContent, config);\n\n return morphNormalizedContent(oldNode, normalizedContent, ctx);\n }\n\n function morphNormalizedContent(oldNode, normalizedNewContent, ctx) {\n if (ctx.head.block) {\n let oldHead = oldNode.querySelector('head');\n let newHead = normalizedNewContent.querySelector('head');\n if (oldHead && newHead) {\n let promises = handleHeadElement(newHead, oldHead, ctx);\n // when head promises resolve, call morph again, ignoring the head tag\n Promise.all(promises).then(function () {\n morphNormalizedContent(oldNode, normalizedNewContent, Object.assign(ctx, {\n head: {\n block: false,\n ignore: true\n }\n }));\n });\n return;\n }\n }\n\n if (ctx.morphStyle === \"innerHTML\") {\n\n // innerHTML, so we are only updating the children\n morphChildren(normalizedNewContent, oldNode, ctx);\n return oldNode.children;\n\n } else if (ctx.morphStyle === \"outerHTML\" || ctx.morphStyle == null) {\n // otherwise find the best element match in the new content, morph that, and merge its siblings\n // into either side of the best match\n let bestMatch = findBestNodeMatch(normalizedNewContent, oldNode, ctx);\n\n // stash the siblings that will need to be inserted on either side of the best match\n let previousSibling = bestMatch?.previousSibling;\n let nextSibling = bestMatch?.nextSibling;\n\n // morph it\n let morphedNode = morphOldNodeTo(oldNode, bestMatch, ctx);\n\n if (bestMatch) {\n // if there was a best match, merge the siblings in too and return the\n // whole bunch\n return insertSiblings(previousSibling, morphedNode, nextSibling);\n } else {\n // otherwise nothing was added to the DOM\n return []\n }\n } else {\n throw \"Do not understand how to morph style \" + ctx.morphStyle;\n }\n }\n\n\n /**\n * @param possibleActiveElement\n * @param ctx\n * @returns {boolean}\n */\n function ignoreValueOfActiveElement(possibleActiveElement, ctx) {\n return ctx.ignoreActiveValue && possibleActiveElement === document.activeElement && possibleActiveElement !== document.body;\n }\n\n /**\n * @param oldNode root node to merge content into\n * @param newContent new content to merge\n * @param ctx the merge context\n * @returns {Element} the element that ended up in the DOM\n */\n function morphOldNodeTo(oldNode, newContent, ctx) {\n if (ctx.ignoreActive && oldNode === document.activeElement) {\n // don't morph focused element\n } else if (newContent == null) {\n if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;\n\n oldNode.remove();\n ctx.callbacks.afterNodeRemoved(oldNode);\n return null;\n } else if (!isSoftMatch(oldNode, newContent)) {\n if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;\n if (ctx.callbacks.beforeNodeAdded(newContent) === false) return oldNode;\n\n oldNode.parentElement.replaceChild(newContent, oldNode);\n ctx.callbacks.afterNodeAdded(newContent);\n ctx.callbacks.afterNodeRemoved(oldNode);\n return newContent;\n } else {\n if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) return oldNode;\n\n if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) {\n // ignore the head element\n } else if (oldNode instanceof HTMLHeadElement && ctx.head.style !== \"morph\") {\n handleHeadElement(newContent, oldNode, ctx);\n } else {\n syncNodeFrom(newContent, oldNode, ctx);\n if (!ignoreValueOfActiveElement(oldNode, ctx)) {\n morphChildren(newContent, oldNode, ctx);\n }\n }\n ctx.callbacks.afterNodeMorphed(oldNode, newContent);\n return oldNode;\n }\n }\n\n /**\n * This is the core algorithm for matching up children. The idea is to use id sets to try to match up\n * nodes as faithfully as possible. We greedily match, which allows us to keep the algorithm fast, but\n * by using id sets, we are able to better match up with content deeper in the DOM.\n *\n * Basic algorithm is, for each node in the new content:\n *\n * - if we have reached the end of the old parent, append the new content\n * - if the new content has an id set match with the current insertion point, morph\n * - search for an id set match\n * - if id set match found, morph\n * - otherwise search for a \"soft\" match\n * - if a soft match is found, morph\n * - otherwise, prepend the new node before the current insertion point\n *\n * The two search algorithms terminate if competing node matches appear to outweigh what can be achieved\n * with the current node. See findIdSetMatch() and findSoftMatch() for details.\n *\n * @param {Element} newParent the parent element of the new content\n * @param {Element } oldParent the old content that we are merging the new content into\n * @param ctx the merge context\n */\n function morphChildren(newParent, oldParent, ctx) {\n\n let nextNewChild = newParent.firstChild;\n let insertionPoint = oldParent.firstChild;\n let newChild;\n\n // run through all the new content\n while (nextNewChild) {\n\n newChild = nextNewChild;\n nextNewChild = newChild.nextSibling;\n\n // if we are at the end of the exiting parent's children, just append\n if (insertionPoint == null) {\n if (ctx.callbacks.beforeNodeAdded(newChild) === false) return;\n\n oldParent.appendChild(newChild);\n ctx.callbacks.afterNodeAdded(newChild);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // if the current node has an id set match then morph\n if (isIdSetMatch(newChild, insertionPoint, ctx)) {\n morphOldNodeTo(insertionPoint, newChild, ctx);\n insertionPoint = insertionPoint.nextSibling;\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // otherwise search forward in the existing old children for an id set match\n let idSetMatch = findIdSetMatch(newParent, oldParent, newChild, insertionPoint, ctx);\n\n // if we found a potential match, remove the nodes until that point and morph\n if (idSetMatch) {\n insertionPoint = removeNodesBetween(insertionPoint, idSetMatch, ctx);\n morphOldNodeTo(idSetMatch, newChild, ctx);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // no id set match found, so scan forward for a soft match for the current node\n let softMatch = findSoftMatch(newParent, oldParent, newChild, insertionPoint, ctx);\n\n // if we found a soft match for the current node, morph\n if (softMatch) {\n insertionPoint = removeNodesBetween(insertionPoint, softMatch, ctx);\n morphOldNodeTo(softMatch, newChild, ctx);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // abandon all hope of morphing, just insert the new child before the insertion point\n // and move on\n if (ctx.callbacks.beforeNodeAdded(newChild) === false) return;\n\n oldParent.insertBefore(newChild, insertionPoint);\n ctx.callbacks.afterNodeAdded(newChild);\n removeIdsFromConsideration(ctx, newChild);\n }\n\n // remove any remaining old nodes that didn't match up with new content\n while (insertionPoint !== null) {\n\n let tempNode = insertionPoint;\n insertionPoint = insertionPoint.nextSibling;\n removeNode(tempNode, ctx);\n }\n }\n\n //=============================================================================\n // Attribute Syncing Code\n //=============================================================================\n\n /**\n * @param attr {String} the attribute to be mutated\n * @param to {Element} the element that is going to be updated\n * @param updateType {(\"update\"|\"remove\")}\n * @param ctx the merge context\n * @returns {boolean} true if the attribute should be ignored, false otherwise\n */\n function ignoreAttribute(attr, to, updateType, ctx) {\n if(attr === 'value' && ctx.ignoreActiveValue && to === document.activeElement){\n return true;\n }\n return ctx.callbacks.beforeAttributeUpdated(attr, to, updateType) === false;\n }\n\n /**\n * syncs a given node with another node, copying over all attributes and\n * inner element state from the 'from' node to the 'to' node\n *\n * @param {Element} from the element to copy attributes & state from\n * @param {Element} to the element to copy attributes & state to\n * @param ctx the merge context\n */\n function syncNodeFrom(from, to, ctx) {\n let type = from.nodeType\n\n // if is an element type, sync the attributes from the\n // new node into the new node\n if (type === 1 /* element type */) {\n const fromAttributes = from.attributes;\n const toAttributes = to.attributes;\n for (const fromAttribute of fromAttributes) {\n if (ignoreAttribute(fromAttribute.name, to, 'update', ctx)) {\n continue;\n }\n if (to.getAttribute(fromAttribute.name) !== fromAttribute.value) {\n to.setAttribute(fromAttribute.name, fromAttribute.value);\n }\n }\n // iterate backwards to avoid skipping over items when a delete occurs\n for (let i = toAttributes.length - 1; 0 <= i; i--) {\n const toAttribute = toAttributes[i];\n if (ignoreAttribute(toAttribute.name, to, 'remove', ctx)) {\n continue;\n }\n if (!from.hasAttribute(toAttribute.name)) {\n to.removeAttribute(toAttribute.name);\n }\n }\n }\n\n // sync text nodes\n if (type === 8 /* comment */ || type === 3 /* text */) {\n if (to.nodeValue !== from.nodeValue) {\n to.nodeValue = from.nodeValue;\n }\n }\n\n if (!ignoreValueOfActiveElement(to, ctx)) {\n // sync input values\n syncInputValue(from, to, ctx);\n }\n }\n\n /**\n * @param from {Element} element to sync the value from\n * @param to {Element} element to sync the value to\n * @param attributeName {String} the attribute name\n * @param ctx the merge context\n */\n function syncBooleanAttribute(from, to, attributeName, ctx) {\n if (from[attributeName] !== to[attributeName]) {\n let ignoreUpdate = ignoreAttribute(attributeName, to, 'update', ctx);\n if (!ignoreUpdate) {\n to[attributeName] = from[attributeName];\n }\n if (from[attributeName]) {\n if (!ignoreUpdate) {\n to.setAttribute(attributeName, from[attributeName]);\n }\n } else {\n if (!ignoreAttribute(attributeName, to, 'remove', ctx)) {\n to.removeAttribute(attributeName);\n }\n }\n }\n }\n\n /**\n * NB: many bothans died to bring us information:\n *\n * https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n * https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113\n *\n * @param from {Element} the element to sync the input value from\n * @param to {Element} the element to sync the input value to\n * @param ctx the merge context\n */\n function syncInputValue(from, to, ctx) {\n if (from instanceof HTMLInputElement &&\n to instanceof HTMLInputElement &&\n from.type !== 'file') {\n\n let fromValue = from.value;\n let toValue = to.value;\n\n // sync boolean attributes\n syncBooleanAttribute(from, to, 'checked', ctx);\n syncBooleanAttribute(from, to, 'disabled', ctx);\n\n if (!from.hasAttribute('value')) {\n if (!ignoreAttribute('value', to, 'remove', ctx)) {\n to.value = '';\n to.removeAttribute('value');\n }\n } else if (fromValue !== toValue) {\n if (!ignoreAttribute('value', to, 'update', ctx)) {\n to.setAttribute('value', fromValue);\n to.value = fromValue;\n }\n }\n } else if (from instanceof HTMLOptionElement) {\n syncBooleanAttribute(from, to, 'selected', ctx)\n } else if (from instanceof HTMLTextAreaElement && to instanceof HTMLTextAreaElement) {\n let fromValue = from.value;\n let toValue = to.value;\n if (ignoreAttribute('value', to, 'update', ctx)) {\n return;\n }\n if (fromValue !== toValue) {\n to.value = fromValue;\n }\n if (to.firstChild && to.firstChild.nodeValue !== fromValue) {\n to.firstChild.nodeValue = fromValue\n }\n }\n }\n\n //=============================================================================\n // the HEAD tag can be handled specially, either w/ a 'merge' or 'append' style\n //=============================================================================\n function handleHeadElement(newHeadTag, currentHead, ctx) {\n\n let added = []\n let removed = []\n let preserved = []\n let nodesToAppend = []\n\n let headMergeStyle = ctx.head.style;\n\n // put all new head elements into a Map, by their outerHTML\n let srcToNewHeadNodes = new Map();\n for (const newHeadChild of newHeadTag.children) {\n srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);\n }\n\n // for each elt in the current head\n for (const currentHeadElt of currentHead.children) {\n\n // If the current head element is in the map\n let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);\n let isReAppended = ctx.head.shouldReAppend(currentHeadElt);\n let isPreserved = ctx.head.shouldPreserve(currentHeadElt);\n if (inNewContent || isPreserved) {\n if (isReAppended) {\n // remove the current version and let the new version replace it and re-execute\n removed.push(currentHeadElt);\n } else {\n // this element already exists and should not be re-appended, so remove it from\n // the new content map, preserving it in the DOM\n srcToNewHeadNodes.delete(currentHeadElt.outerHTML);\n preserved.push(currentHeadElt);\n }\n } else {\n if (headMergeStyle === \"append\") {\n // we are appending and this existing element is not new content\n // so if and only if it is marked for re-append do we do anything\n if (isReAppended) {\n removed.push(currentHeadElt);\n nodesToAppend.push(currentHeadElt);\n }\n } else {\n // if this is a merge, we remove this content since it is not in the new head\n if (ctx.head.shouldRemove(currentHeadElt) !== false) {\n removed.push(currentHeadElt);\n }\n }\n }\n }\n\n // Push the remaining new head elements in the Map into the\n // nodes to append to the head tag\n nodesToAppend.push(...srcToNewHeadNodes.values());\n log(\"to append: \", nodesToAppend);\n\n let promises = [];\n for (const newNode of nodesToAppend) {\n log(\"adding: \", newNode);\n let newElt = document.createRange().createContextualFragment(newNode.outerHTML).firstChild;\n log(newElt);\n if (ctx.callbacks.beforeNodeAdded(newElt) !== false) {\n if (newElt.href || newElt.src) {\n let resolve = null;\n let promise = new Promise(function (_resolve) {\n resolve = _resolve;\n });\n newElt.addEventListener('load', function () {\n resolve();\n });\n promises.push(promise);\n }\n currentHead.appendChild(newElt);\n ctx.callbacks.afterNodeAdded(newElt);\n added.push(newElt);\n }\n }\n\n // remove all removed elements, after we have appended the new elements to avoid\n // additional network requests for things like style sheets\n for (const removedElement of removed) {\n if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {\n currentHead.removeChild(removedElement);\n ctx.callbacks.afterNodeRemoved(removedElement);\n }\n }\n\n ctx.head.afterHeadMorphed(currentHead, {added: added, kept: preserved, removed: removed});\n return promises;\n }\n\n //=============================================================================\n // Misc\n //=============================================================================\n\n function log() {\n //console.log(arguments);\n }\n\n function noOp() {\n }\n\n /*\n Deep merges the config object and the Idiomoroph.defaults object to\n produce a final configuration object\n */\n function mergeDefaults(config) {\n let finalConfig = {};\n // copy top level stuff into final config\n Object.assign(finalConfig, defaults);\n Object.assign(finalConfig, config);\n\n // copy callbacks into final config (do this to deep merge the callbacks)\n finalConfig.callbacks = {};\n Object.assign(finalConfig.callbacks, defaults.callbacks);\n Object.assign(finalConfig.callbacks, config.callbacks);\n\n // copy head config into final config (do this to deep merge the head)\n finalConfig.head = {};\n Object.assign(finalConfig.head, defaults.head);\n Object.assign(finalConfig.head, config.head);\n return finalConfig;\n }\n\n function createMorphContext(oldNode, newContent, config) {\n config = mergeDefaults(config);\n return {\n target: oldNode,\n newContent: newContent,\n config: config,\n morphStyle: config.morphStyle,\n ignoreActive: config.ignoreActive,\n ignoreActiveValue: config.ignoreActiveValue,\n idMap: createIdMap(oldNode, newContent),\n deadIds: new Set(),\n callbacks: config.callbacks,\n head: config.head\n }\n }\n\n function isIdSetMatch(node1, node2, ctx) {\n if (node1 == null || node2 == null) {\n return false;\n }\n if (node1.nodeType === node2.nodeType && node1.tagName === node2.tagName) {\n if (node1.id !== \"\" && node1.id === node2.id) {\n return true;\n } else {\n return getIdIntersectionCount(ctx, node1, node2) > 0;\n }\n }\n return false;\n }\n\n function isSoftMatch(node1, node2) {\n if (node1 == null || node2 == null) {\n return false;\n }\n return node1.nodeType === node2.nodeType && node1.tagName === node2.tagName\n }\n\n function removeNodesBetween(startInclusive, endExclusive, ctx) {\n while (startInclusive !== endExclusive) {\n let tempNode = startInclusive;\n startInclusive = startInclusive.nextSibling;\n removeNode(tempNode, ctx);\n }\n removeIdsFromConsideration(ctx, endExclusive);\n return endExclusive.nextSibling;\n }\n\n //=============================================================================\n // Scans forward from the insertionPoint in the old parent looking for a potential id match\n // for the newChild. We stop if we find a potential id match for the new child OR\n // if the number of potential id matches we are discarding is greater than the\n // potential id matches for the new child\n //=============================================================================\n function findIdSetMatch(newContent, oldParent, newChild, insertionPoint, ctx) {\n\n // max id matches we are willing to discard in our search\n let newChildPotentialIdCount = getIdIntersectionCount(ctx, newChild, oldParent);\n\n let potentialMatch = null;\n\n // only search forward if there is a possibility of an id match\n if (newChildPotentialIdCount > 0) {\n let potentialMatch = insertionPoint;\n // if there is a possibility of an id match, scan forward\n // keep track of the potential id match count we are discarding (the\n // newChildPotentialIdCount must be greater than this to make it likely\n // worth it)\n let otherMatchCount = 0;\n while (potentialMatch != null) {\n\n // If we have an id match, return the current potential match\n if (isIdSetMatch(newChild, potentialMatch, ctx)) {\n return potentialMatch;\n }\n\n // computer the other potential matches of this new content\n otherMatchCount += getIdIntersectionCount(ctx, potentialMatch, newContent);\n if (otherMatchCount > newChildPotentialIdCount) {\n // if we have more potential id matches in _other_ content, we\n // do not have a good candidate for an id match, so return null\n return null;\n }\n\n // advanced to the next old content child\n potentialMatch = potentialMatch.nextSibling;\n }\n }\n return potentialMatch;\n }\n\n //=============================================================================\n // Scans forward from the insertionPoint in the old parent looking for a potential soft match\n // for the newChild. We stop if we find a potential soft match for the new child OR\n // if we find a potential id match in the old parents children OR if we find two\n // potential soft matches for the next two pieces of new content\n //=============================================================================\n function findSoftMatch(newContent, oldParent, newChild, insertionPoint, ctx) {\n\n let potentialSoftMatch = insertionPoint;\n let nextSibling = newChild.nextSibling;\n let siblingSoftMatchCount = 0;\n\n while (potentialSoftMatch != null) {\n\n if (getIdIntersectionCount(ctx, potentialSoftMatch, newContent) > 0) {\n // the current potential soft match has a potential id set match with the remaining new\n // content so bail out of looking\n return null;\n }\n\n // if we have a soft match with the current node, return it\n if (isSoftMatch(newChild, potentialSoftMatch)) {\n return potentialSoftMatch;\n }\n\n if (isSoftMatch(nextSibling, potentialSoftMatch)) {\n // the next new node has a soft match with this node, so\n // increment the count of future soft matches\n siblingSoftMatchCount++;\n nextSibling = nextSibling.nextSibling;\n\n // If there are two future soft matches, bail to allow the siblings to soft match\n // so that we don't consume future soft matches for the sake of the current node\n if (siblingSoftMatchCount >= 2) {\n return null;\n }\n }\n\n // advanced to the next old content child\n potentialSoftMatch = potentialSoftMatch.nextSibling;\n }\n\n return potentialSoftMatch;\n }\n\n function parseContent(newContent) {\n let parser = new DOMParser();\n\n // remove svgs to avoid false-positive matches on head, etc.\n let contentWithSvgsRemoved = newContent.replace(/<svg(\\s[^>]*>|>)([\\s\\S]*?)<\\/svg>/gim, '');\n\n // if the newContent contains a html, head or body tag, we can simply parse it w/o wrapping\n if (contentWithSvgsRemoved.match(/<\\/html>/) || contentWithSvgsRemoved.match(/<\\/head>/) || contentWithSvgsRemoved.match(/<\\/body>/)) {\n let content = parser.parseFromString(newContent, \"text/html\");\n // if it is a full HTML document, return the document itself as the parent container\n if (contentWithSvgsRemoved.match(/<\\/html>/)) {\n content.generatedByIdiomorph = true;\n return content;\n } else {\n // otherwise return the html element as the parent container\n let htmlElement = content.firstChild;\n if (htmlElement) {\n htmlElement.generatedByIdiomorph = true;\n return htmlElement;\n } else {\n return null;\n }\n }\n } else {\n // if it is partial HTML, wrap it in a template tag to provide a parent element and also to help\n // deal with touchy tags like tr, tbody, etc.\n let responseDoc = parser.parseFromString(\"<body><template>\" + newContent + \"</template></body>\", \"text/html\");\n let content = responseDoc.body.querySelector('template').content;\n content.generatedByIdiomorph = true;\n return content\n }\n }\n\n function normalizeContent(newContent) {\n if (newContent == null) {\n // noinspection UnnecessaryLocalVariableJS\n const dummyParent = document.createElement('div');\n return dummyParent;\n } else if (newContent.generatedByIdiomorph) {\n // the template tag created by idiomorph parsing can serve as a dummy parent\n return newContent;\n } else if (newContent instanceof Node) {\n // a single node is added as a child to a dummy parent\n const dummyParent = document.createElement('div');\n dummyParent.append(newContent);\n return dummyParent;\n } else {\n // all nodes in the array or HTMLElement collection are consolidated under\n // a single dummy parent element\n const dummyParent = document.createElement('div');\n for (const elt of [...newContent]) {\n dummyParent.append(elt);\n }\n return dummyParent;\n }\n }\n\n function insertSiblings(previousSibling, morphedNode, nextSibling) {\n let stack = []\n let added = []\n while (previousSibling != null) {\n stack.push(previousSibling);\n previousSibling = previousSibling.previousSibling;\n }\n while (stack.length > 0) {\n let node = stack.pop();\n added.push(node); // push added preceding siblings on in order and insert\n morphedNode.parentElement.insertBefore(node, morphedNode);\n }\n added.push(morphedNode);\n while (nextSibling != null) {\n stack.push(nextSibling);\n added.push(nextSibling); // here we are going in order, so push on as we scan, rather than add\n nextSibling = nextSibling.nextSibling;\n }\n while (stack.length > 0) {\n morphedNode.parentElement.insertBefore(stack.pop(), morphedNode.nextSibling);\n }\n return added;\n }\n\n function findBestNodeMatch(newContent, oldNode, ctx) {\n let currentElement;\n currentElement = newContent.firstChild;\n let bestElement = currentElement;\n let score = 0;\n while (currentElement) {\n let newScore = scoreElement(currentElement, oldNode, ctx);\n if (newScore > score) {\n bestElement = currentElement;\n score = newScore;\n }\n currentElement = currentElement.nextSibling;\n }\n return bestElement;\n }\n\n function scoreElement(node1, node2, ctx) {\n if (isSoftMatch(node1, node2)) {\n return .5 + getIdIntersectionCount(ctx, node1, node2);\n }\n return 0;\n }\n\n function removeNode(tempNode, ctx) {\n removeIdsFromConsideration(ctx, tempNode)\n if (ctx.callbacks.beforeNodeRemoved(tempNode) === false) return;\n\n tempNode.remove();\n ctx.callbacks.afterNodeRemoved(tempNode);\n }\n\n //=============================================================================\n // ID Set Functions\n //=============================================================================\n\n function isIdInConsideration(ctx, id) {\n return !ctx.deadIds.has(id);\n }\n\n function idIsWithinNode(ctx, id, targetNode) {\n let idSet = ctx.idMap.get(targetNode) || EMPTY_SET;\n return idSet.has(id);\n }\n\n function removeIdsFromConsideration(ctx, node) {\n let idSet = ctx.idMap.get(node) || EMPTY_SET;\n for (const id of idSet) {\n ctx.deadIds.add(id);\n }\n }\n\n function getIdIntersectionCount(ctx, node1, node2) {\n let sourceSet = ctx.idMap.get(node1) || EMPTY_SET;\n let matchCount = 0;\n for (const id of sourceSet) {\n // a potential match is an id in the source and potentialIdsSet, but\n // that has not already been merged into the DOM\n if (isIdInConsideration(ctx, id) && idIsWithinNode(ctx, id, node2)) {\n ++matchCount;\n }\n }\n return matchCount;\n }\n\n /**\n * A bottom up algorithm that finds all elements with ids inside of the node\n * argument and populates id sets for those nodes and all their parents, generating\n * a set of ids contained within all nodes for the entire hierarchy in the DOM\n *\n * @param node {Element}\n * @param {Map<Node, Set<String>>} idMap\n */\n function populateIdMapForNode(node, idMap) {\n let nodeParent = node.parentElement;\n // find all elements with an id property\n let idElements = node.querySelectorAll('[id]');\n for (const elt of idElements) {\n let current = elt;\n // walk up the parent hierarchy of that element, adding the id\n // of element to the parent's id set\n while (current !== nodeParent && current != null) {\n let idSet = idMap.get(current);\n // if the id set doesn't exist, create it and insert it in the map\n if (idSet == null) {\n idSet = new Set();\n idMap.set(current, idSet);\n }\n idSet.add(elt.id);\n current = current.parentElement;\n }\n }\n }\n\n /**\n * This function computes a map of nodes to all ids contained within that node (inclusive of the\n * node). This map can be used to ask if two nodes have intersecting sets of ids, which allows\n * for a looser definition of \"matching\" than tradition id matching, and allows child nodes\n * to contribute to a parent nodes matching.\n *\n * @param {Element} oldContent the old content that will be morphed\n * @param {Element} newContent the new content to morph to\n * @returns {Map<Node, Set<String>>} a map of nodes to id sets for the\n */\n function createIdMap(oldContent, newContent) {\n let idMap = new Map();\n populateIdMapForNode(oldContent, idMap);\n populateIdMapForNode(newContent, idMap);\n return idMap;\n }\n\n //=============================================================================\n // This is what ends up becoming the Idiomorph global object\n //=============================================================================\n return {\n morph,\n defaults\n }\n })();\n\nexport {Idiomorph};\n", "import { Idiomorph } from 'idiomorph'\nimport schema from './schema'\n\nlet _method\nlet _delay = 0\n\nconst trixEditor = /TRIX-EDITOR/i\n\nfunction isElement(node) {\n return node.nodeType === Node.ELEMENT_NODE\n}\n\nfunction isTurboPermanent(node) {\n if (!isElement(node)) return false\n return (\n node.hasAttribute(schema.turboPermanentAttribute) &&\n node.getAttribute(schema.turboPermanentAttribute) !== 'false'\n )\n}\n\nfunction isActive(node) {\n if (!isElement(node)) return false\n return node === document.activeElement\n}\n\nfunction morphAllowed(node) {\n if (isTurboPermanent(node)) return false\n if (isActive(node) && node.tagName.match(trixEditor)) return false\n return true\n}\n\nconst defaultOptions = {\n callbacks: { beforeNodeMorphed: (oldNode, _newNode) => morphAllowed(oldNode) },\n morphStyle: 'outerHTML',\n ignoreActiveValue: true,\n head: { style: 'merge' }\n}\n\nfunction morph(element, html, options = {}) {\n const callbacks = { ...defaultOptions.callbacks, ...options.callbacks }\n options = { ...defaultOptions, ...options, callbacks }\n\n return new Promise(resolve => {\n setTimeout(() => {\n Idiomorph.morph(element, html, options)\n resolve()\n }, _delay)\n })\n}\n\n_method = morph\n\nexport default {\n get delay() {\n return _delay\n },\n\n set delay(ms) {\n _delay = ms\n },\n\n get method() {\n return _method\n },\n\n set method(fn) {\n _method = fn\n }\n}\n", "import morph from './morph'\n\nconst invokeEvents = {\n before: 'turbo-boost:stream:before-invoke',\n after: 'turbo-boost:stream:after-invoke',\n finish: 'turbo-boost:stream:finish-invoke'\n}\n\n// Invokes the callback on a single receiver with before/after events\nfunction withInvokeEvents(receiver, detail, callback) {\n const { object, target } = receiver\n detail = detail || {}\n detail = { ...detail, object: receiver.object }\n const options = { detail, bubbles: true }\n\n target.dispatchEvent(new CustomEvent(invokeEvents.before, options))\n\n // the before event can provide invoke instructions my modifying the event detail\n // For example, { delay: 1000 } will delay the invocation by 1000ms\n let { delay } = detail.invoke || {}\n delay = delay || 0\n\n const execute = () => {\n const result = callback(object)\n options.detail.result = result\n target.dispatchEvent(new CustomEvent(invokeEvents.after, options))\n\n let promise\n if (result instanceof Animation) promise = result.finished\n if (result instanceof Promise) promise = result\n\n if (promise)\n promise\n .then(() => {\n options.detail.promise = 'fulfilled'\n target.dispatchEvent(new CustomEvent(invokeEvents.finish, options))\n })\n .catch(error => {\n options.detail.promise = 'rejected'\n options.detail.error = error\n target.dispatchEvent(new CustomEvent(invokeEvents.finish, options))\n })\n else target.dispatchEvent(new CustomEvent(invokeEvents.finish, options))\n }\n\n if (delay > 0) setTimeout(execute, delay)\n else execute()\n}\n\nfunction invokeDispatchEvent(method, args, receivers) {\n const eventName = args[0]\n const eventOptions = args[1]\n const detail = { method, eventName, eventOptions }\n receivers.forEach(receiver =>\n withInvokeEvents(receiver, detail, object =>\n object.dispatchEvent(new CustomEvent(eventName, eventOptions))\n )\n )\n}\n\nfunction invokeMorph(method, args, receivers) {\n const html = args[0]\n const detail = { method, html }\n receivers.forEach(receiver => withInvokeEvents(receiver, detail, object => morph.method(object, html)))\n}\n\nfunction invokeAssignment(method, args, receivers) {\n const property = method.slice(0, -1).trim()\n const value = args[0]\n const detail = { method, property, value }\n receivers.forEach(receiver => withInvokeEvents(receiver, detail, object => (object[property] = value)))\n}\n\nfunction invokeMethod(method, args, receivers) {\n const detail = { method, args }\n receivers.forEach(receiver =>\n withInvokeEvents(receiver, detail, object => object[method].apply(object, args))\n )\n}\n\n// Performs an invocation on all receivers for the given method and args\nfunction performInvoke(method, args, receivers) {\n // dispatch ................................................................................................\n if (method.match(/^dispatch(Event)?$/)) return invokeDispatchEvent(method, args, receivers)\n\n // morph ...................................................................................................\n if (method.match(/^morph|mutate$/)) return invokeMorph(method, args, receivers)\n\n // assignment ..............................................................................................\n if (method.endsWith('=')) return invokeAssignment(method, args, receivers)\n\n // method ..................................................................................................\n return invokeMethod(method, args, receivers)\n}\n\nfunction invoke() {\n const payload = JSON.parse(this.templateContent.textContent)\n const { id, selector, receiver, method, args, delay } = payload\n let receivers = [{ object: self, target: self }]\n if (selector)\n receivers = Array.from(document.querySelectorAll(selector)).map(el => ({\n object: el,\n target: el\n }))\n\n if (receiver) {\n receivers = receivers.map(r => {\n let { object, target } = r\n const chain = receiver.split('.')\n while (chain.length > 0) {\n object = object[chain.shift()]\n if (object.dispatchEvent) target = object\n }\n return { object, target }\n })\n }\n\n if (delay > 0) setTimeout(() => performInvoke(method, args, receivers), delay)\n else performInvoke(method, args, receivers)\n}\n\nexport { invoke, invokeEvents }\n", "import VERSION from './version'\nimport schema from './schema'\nimport morph from './morph'\nimport { invoke, invokeEvents } from './invoke'\n\nif (!self['Turbo'])\n throw new Error(\n '`Turbo` is not defined! Be sure to import `@turbo-boost/streams` after `@hotwired/turbo` or `@hotwired/turbo-rails`.'\n )\n\nif (!Turbo['StreamActions'])\n throw new Error(\n '`Turbo.StreamActions` is not defined! Verify that you are running >= `7.2.0` of `@hotwired/turbo`.'\n )\n\nTurbo.StreamActions.invoke = invoke\nself.TurboBoost = self.TurboBoost || {}\nself.TurboBoost.Streams = { invoke, invokeEvents, morph, schema, VERSION }\n\nconsole.info('@turbo-boost/streams has initialized and registered new stream actions with Turbo.')\n\nexport default self.TurboBoost.Streams\n"],
5
+ "mappings": "ubAAA,IAAOA,EAAQ,SCAf,IAAMC,GAAS,CACb,wBAAyB,sBAC3B,EAEOC,EAAQC,EAAA,GAAKF,ICHpB,IAAIG,EAAa,UAAY,CACrB,aAKA,IAAIC,EAAY,IAAI,IAGhBC,EAAW,CACX,WAAY,YACZ,UAAY,CACR,gBAAiBC,EACjB,eAAgBA,EAChB,kBAAmBA,EACnB,iBAAkBA,EAClB,kBAAmBA,EACnB,iBAAkBA,EAClB,uBAAwBA,CAE5B,EACA,KAAM,CACF,MAAO,QACP,eAAgB,SAAUC,EAAK,CAC3B,OAAOA,EAAI,aAAa,aAAa,IAAM,MAC/C,EACA,eAAgB,SAAUA,EAAK,CAC3B,OAAOA,EAAI,aAAa,cAAc,IAAM,MAChD,EACA,aAAcD,EACd,iBAAkBA,CACtB,CACJ,EAKA,SAASE,EAAMC,EAASC,EAAYC,EAAS,CAAC,EAAG,CAEzCF,aAAmB,WACnBA,EAAUA,EAAQ,iBAGlB,OAAOC,GAAe,WACtBA,EAAaE,GAAaF,CAAU,GAGxC,IAAIG,EAAoBC,GAAiBJ,CAAU,EAE/CK,EAAMC,EAAmBP,EAASI,EAAmBF,CAAM,EAE/D,OAAOM,EAAuBR,EAASI,EAAmBE,CAAG,CACjE,CAEA,SAASE,EAAuBR,EAASS,EAAsBH,EAAK,CAChE,GAAIA,EAAI,KAAK,MAAO,CAChB,IAAII,EAAUV,EAAQ,cAAc,MAAM,EACtCW,EAAUF,EAAqB,cAAc,MAAM,EACvD,GAAIC,GAAWC,EAAS,CACpB,IAAIC,EAAWC,EAAkBF,EAASD,EAASJ,CAAG,EAEtD,QAAQ,IAAIM,CAAQ,EAAE,KAAK,UAAY,CACnCJ,EAAuBR,EAASS,EAAsB,OAAO,OAAOH,EAAK,CACrE,KAAM,CACF,MAAO,GACP,OAAQ,EACZ,CACJ,CAAC,CAAC,CACN,CAAC,EACD,MACJ,CACJ,CAEA,GAAIA,EAAI,aAAe,YAGnB,OAAAQ,EAAcL,EAAsBT,EAASM,CAAG,EACzCN,EAAQ,SAEZ,GAAIM,EAAI,aAAe,aAAeA,EAAI,YAAc,KAAM,CAGjE,IAAIS,EAAYC,GAAkBP,EAAsBT,EAASM,CAAG,EAGhEW,EAAkBF,GAAA,YAAAA,EAAW,gBAC7BG,EAAcH,GAAA,YAAAA,EAAW,YAGzBI,EAAcC,EAAepB,EAASe,EAAWT,CAAG,EAExD,OAAIS,EAGOM,GAAeJ,EAAiBE,EAAaD,CAAW,EAGxD,CAAC,CAEhB,KACI,MAAM,wCAA0CZ,EAAI,UAE5D,CAQA,SAASgB,EAA2BC,EAAuBjB,EAAK,CAC5D,OAAOA,EAAI,mBAAqBiB,IAA0B,SAAS,eAAiBA,IAA0B,SAAS,IAC3H,CAQA,SAASH,EAAepB,EAASC,EAAYK,EAAK,CAC9C,GAAI,EAAAA,EAAI,cAAgBN,IAAY,SAAS,eAEtC,OAAIC,GAAc,KACjBK,EAAI,UAAU,kBAAkBN,CAAO,IAAM,GAAcA,GAE/DA,EAAQ,OAAO,EACfM,EAAI,UAAU,iBAAiBN,CAAO,EAC/B,MACCwB,EAAYxB,EAASC,CAAU,GASnCK,EAAI,UAAU,kBAAkBN,EAASC,CAAU,IAAM,KAEzDD,aAAmB,iBAAmBM,EAAI,KAAK,SAExCN,aAAmB,iBAAmBM,EAAI,KAAK,QAAU,QAChEO,EAAkBZ,EAAYD,EAASM,CAAG,GAE1CmB,EAAaxB,EAAYD,EAASM,CAAG,EAChCgB,EAA2BtB,EAASM,CAAG,GACxCQ,EAAcb,EAAYD,EAASM,CAAG,IAG9CA,EAAI,UAAU,iBAAiBN,EAASC,CAAU,GAC3CD,GArBHM,EAAI,UAAU,kBAAkBN,CAAO,IAAM,IAC7CM,EAAI,UAAU,gBAAgBL,CAAU,IAAM,GAAcD,GAEhEA,EAAQ,cAAc,aAAaC,EAAYD,CAAO,EACtDM,EAAI,UAAU,eAAeL,CAAU,EACvCK,EAAI,UAAU,iBAAiBN,CAAO,EAC/BC,EAiBf,CAwBA,SAASa,EAAcY,EAAWC,EAAWrB,EAAK,CAE9C,IAAIsB,EAAeF,EAAU,WACzBG,EAAiBF,EAAU,WAC3BG,EAGJ,KAAOF,GAAc,CAMjB,GAJAE,EAAWF,EACXA,EAAeE,EAAS,YAGpBD,GAAkB,KAAM,CACxB,GAAIvB,EAAI,UAAU,gBAAgBwB,CAAQ,IAAM,GAAO,OAEvDH,EAAU,YAAYG,CAAQ,EAC9BxB,EAAI,UAAU,eAAewB,CAAQ,EACrCC,EAA2BzB,EAAKwB,CAAQ,EACxC,QACJ,CAGA,GAAIE,EAAaF,EAAUD,EAAgBvB,CAAG,EAAG,CAC7Cc,EAAeS,EAAgBC,EAAUxB,CAAG,EAC5CuB,EAAiBA,EAAe,YAChCE,EAA2BzB,EAAKwB,CAAQ,EACxC,QACJ,CAGA,IAAIG,EAAaC,EAAeR,EAAWC,EAAWG,EAAUD,EAAgBvB,CAAG,EAGnF,GAAI2B,EAAY,CACZJ,EAAiBM,EAAmBN,EAAgBI,EAAY3B,CAAG,EACnEc,EAAea,EAAYH,EAAUxB,CAAG,EACxCyB,EAA2BzB,EAAKwB,CAAQ,EACxC,QACJ,CAGA,IAAIM,EAAYC,EAAcX,EAAWC,EAAWG,EAAUD,EAAgBvB,CAAG,EAGjF,GAAI8B,EAAW,CACXP,EAAiBM,EAAmBN,EAAgBO,EAAW9B,CAAG,EAClEc,EAAegB,EAAWN,EAAUxB,CAAG,EACvCyB,EAA2BzB,EAAKwB,CAAQ,EACxC,QACJ,CAIA,GAAIxB,EAAI,UAAU,gBAAgBwB,CAAQ,IAAM,GAAO,OAEvDH,EAAU,aAAaG,EAAUD,CAAc,EAC/CvB,EAAI,UAAU,eAAewB,CAAQ,EACrCC,EAA2BzB,EAAKwB,CAAQ,CAC5C,CAGA,KAAOD,IAAmB,MAAM,CAE5B,IAAIS,EAAWT,EACfA,EAAiBA,EAAe,YAChCU,EAAWD,EAAUhC,CAAG,CAC5B,CACJ,CAaA,SAASkC,EAAgBC,EAAMC,EAAIC,EAAYrC,EAAK,CAChD,OAAGmC,IAAS,SAAWnC,EAAI,mBAAqBoC,IAAO,SAAS,cACrD,GAEJpC,EAAI,UAAU,uBAAuBmC,EAAMC,EAAIC,CAAU,IAAM,EAC1E,CAUA,SAASlB,EAAamB,EAAMF,EAAIpC,EAAK,CACjC,IAAIuC,EAAOD,EAAK,SAIhB,GAAIC,IAAS,EAAsB,CAC/B,IAAMC,EAAiBF,EAAK,WACtBG,EAAeL,EAAG,WACxB,QAAWM,KAAiBF,EACpBN,EAAgBQ,EAAc,KAAMN,EAAI,SAAUpC,CAAG,GAGrDoC,EAAG,aAAaM,EAAc,IAAI,IAAMA,EAAc,OACtDN,EAAG,aAAaM,EAAc,KAAMA,EAAc,KAAK,EAI/D,QAASC,EAAIF,EAAa,OAAS,EAAG,GAAKE,EAAGA,IAAK,CAC/C,IAAMC,EAAcH,EAAaE,CAAC,EAC9BT,EAAgBU,EAAY,KAAMR,EAAI,SAAUpC,CAAG,GAGlDsC,EAAK,aAAaM,EAAY,IAAI,GACnCR,EAAG,gBAAgBQ,EAAY,IAAI,CAE3C,CACJ,EAGIL,IAAS,GAAmBA,IAAS,IACjCH,EAAG,YAAcE,EAAK,YACtBF,EAAG,UAAYE,EAAK,WAIvBtB,EAA2BoB,EAAIpC,CAAG,GAEnC6C,EAAeP,EAAMF,EAAIpC,CAAG,CAEpC,CAQA,SAAS8C,EAAqBR,EAAMF,EAAIW,EAAe/C,EAAK,CACxD,GAAIsC,EAAKS,CAAa,IAAMX,EAAGW,CAAa,EAAG,CAC3C,IAAIC,EAAed,EAAgBa,EAAeX,EAAI,SAAUpC,CAAG,EAC9DgD,IACDZ,EAAGW,CAAa,EAAIT,EAAKS,CAAa,GAEtCT,EAAKS,CAAa,EACbC,GACDZ,EAAG,aAAaW,EAAeT,EAAKS,CAAa,CAAC,EAGjDb,EAAgBa,EAAeX,EAAI,SAAUpC,CAAG,GACjDoC,EAAG,gBAAgBW,CAAa,CAG5C,CACJ,CAYA,SAASF,EAAeP,EAAMF,EAAIpC,EAAK,CACnC,GAAIsC,aAAgB,kBAChBF,aAAc,kBACdE,EAAK,OAAS,OAAQ,CAEtB,IAAIW,EAAYX,EAAK,MACjBY,EAAUd,EAAG,MAGjBU,EAAqBR,EAAMF,EAAI,UAAWpC,CAAG,EAC7C8C,EAAqBR,EAAMF,EAAI,WAAYpC,CAAG,EAEzCsC,EAAK,aAAa,OAAO,EAKnBW,IAAcC,IAChBhB,EAAgB,QAASE,EAAI,SAAUpC,CAAG,IAC3CoC,EAAG,aAAa,QAASa,CAAS,EAClCb,EAAG,MAAQa,IAPVf,EAAgB,QAASE,EAAI,SAAUpC,CAAG,IAC3CoC,EAAG,MAAQ,GACXA,EAAG,gBAAgB,OAAO,EAQtC,SAAWE,aAAgB,kBACvBQ,EAAqBR,EAAMF,EAAI,WAAYpC,CAAG,UACvCsC,aAAgB,qBAAuBF,aAAc,oBAAqB,CACjF,IAAIa,EAAYX,EAAK,MACjBY,EAAUd,EAAG,MACjB,GAAIF,EAAgB,QAASE,EAAI,SAAUpC,CAAG,EAC1C,OAEAiD,IAAcC,IACdd,EAAG,MAAQa,GAEXb,EAAG,YAAcA,EAAG,WAAW,YAAca,IAC7Cb,EAAG,WAAW,UAAYa,EAElC,CACJ,CAKA,SAAS1C,EAAkB4C,EAAYC,EAAapD,EAAK,CAErD,IAAIqD,EAAQ,CAAC,EACTC,EAAU,CAAC,EACXC,EAAY,CAAC,EACbC,EAAgB,CAAC,EAEjBC,EAAiBzD,EAAI,KAAK,MAG1B0D,EAAoB,IAAI,IAC5B,QAAWC,KAAgBR,EAAW,SAClCO,EAAkB,IAAIC,EAAa,UAAWA,CAAY,EAI9D,QAAWC,KAAkBR,EAAY,SAAU,CAG/C,IAAIS,EAAeH,EAAkB,IAAIE,EAAe,SAAS,EAC7DE,EAAe9D,EAAI,KAAK,eAAe4D,CAAc,EACrDG,EAAc/D,EAAI,KAAK,eAAe4D,CAAc,EACpDC,GAAgBE,EACZD,EAEAR,EAAQ,KAAKM,CAAc,GAI3BF,EAAkB,OAAOE,EAAe,SAAS,EACjDL,EAAU,KAAKK,CAAc,GAG7BH,IAAmB,SAGfK,IACAR,EAAQ,KAAKM,CAAc,EAC3BJ,EAAc,KAAKI,CAAc,GAIjC5D,EAAI,KAAK,aAAa4D,CAAc,IAAM,IAC1CN,EAAQ,KAAKM,CAAc,CAI3C,CAIAJ,EAAc,KAAK,GAAGE,EAAkB,OAAO,CAAC,EAGhD,IAAIpD,EAAW,CAAC,EAChB,QAAW0D,KAAWR,EAAe,CAEjC,IAAIS,EAAS,SAAS,YAAY,EAAE,yBAAyBD,EAAQ,SAAS,EAAE,WAEhF,GAAIhE,EAAI,UAAU,gBAAgBiE,CAAM,IAAM,GAAO,CACjD,GAAIA,EAAO,MAAQA,EAAO,IAAK,CAC3B,IAAIC,EAAU,KACVC,EAAU,IAAI,QAAQ,SAAUC,GAAU,CAC1CF,EAAUE,EACd,CAAC,EACDH,EAAO,iBAAiB,OAAQ,UAAY,CACxCC,EAAQ,CACZ,CAAC,EACD5D,EAAS,KAAK6D,CAAO,CACzB,CACAf,EAAY,YAAYa,CAAM,EAC9BjE,EAAI,UAAU,eAAeiE,CAAM,EACnCZ,EAAM,KAAKY,CAAM,CACrB,CACJ,CAIA,QAAWI,KAAkBf,EACrBtD,EAAI,UAAU,kBAAkBqE,CAAc,IAAM,KACpDjB,EAAY,YAAYiB,CAAc,EACtCrE,EAAI,UAAU,iBAAiBqE,CAAc,GAIrD,OAAArE,EAAI,KAAK,iBAAiBoD,EAAa,CAAC,MAAOC,EAAO,KAAME,EAAW,QAASD,CAAO,CAAC,EACjFhD,CACX,CAMA,SAASgE,IAAM,CAEf,CAEA,SAAS/E,GAAO,CAChB,CAMA,SAASgF,EAAc3E,EAAQ,CAC3B,IAAI4E,EAAc,CAAC,EAEnB,cAAO,OAAOA,EAAalF,CAAQ,EACnC,OAAO,OAAOkF,EAAa5E,CAAM,EAGjC4E,EAAY,UAAY,CAAC,EACzB,OAAO,OAAOA,EAAY,UAAWlF,EAAS,SAAS,EACvD,OAAO,OAAOkF,EAAY,UAAW5E,EAAO,SAAS,EAGrD4E,EAAY,KAAO,CAAC,EACpB,OAAO,OAAOA,EAAY,KAAMlF,EAAS,IAAI,EAC7C,OAAO,OAAOkF,EAAY,KAAM5E,EAAO,IAAI,EACpC4E,CACX,CAEA,SAASvE,EAAmBP,EAASC,EAAYC,EAAQ,CACrD,OAAAA,EAAS2E,EAAc3E,CAAM,EACtB,CACH,OAAQF,EACR,WAAYC,EACZ,OAAQC,EACR,WAAYA,EAAO,WACnB,aAAcA,EAAO,aACrB,kBAAmBA,EAAO,kBAC1B,MAAO6E,GAAY/E,EAASC,CAAU,EACtC,QAAS,IAAI,IACb,UAAWC,EAAO,UAClB,KAAMA,EAAO,IACjB,CACJ,CAEA,SAAS8B,EAAagD,EAAOC,EAAO3E,EAAK,CACrC,OAAI0E,GAAS,MAAQC,GAAS,KACnB,GAEPD,EAAM,WAAaC,EAAM,UAAYD,EAAM,UAAYC,EAAM,QACzDD,EAAM,KAAO,IAAMA,EAAM,KAAOC,EAAM,GAC/B,GAEAC,EAAuB5E,EAAK0E,EAAOC,CAAK,EAAI,EAGpD,EACX,CAEA,SAASzD,EAAYwD,EAAOC,EAAO,CAC/B,OAAID,GAAS,MAAQC,GAAS,KACnB,GAEJD,EAAM,WAAaC,EAAM,UAAYD,EAAM,UAAYC,EAAM,OACxE,CAEA,SAAS9C,EAAmBgD,EAAgBC,EAAc9E,EAAK,CAC3D,KAAO6E,IAAmBC,GAAc,CACpC,IAAI9C,EAAW6C,EACfA,EAAiBA,EAAe,YAChC5C,EAAWD,EAAUhC,CAAG,CAC5B,CACA,OAAAyB,EAA2BzB,EAAK8E,CAAY,EACrCA,EAAa,WACxB,CAQA,SAASlD,EAAejC,EAAY0B,EAAWG,EAAUD,EAAgBvB,EAAK,CAG1E,IAAI+E,EAA2BH,EAAuB5E,EAAKwB,EAAUH,CAAS,EAE1E2D,EAAiB,KAGrB,GAAID,EAA2B,EAAG,CAC9B,IAAIC,EAAiBzD,EAKjB0D,EAAkB,EACtB,KAAOD,GAAkB,MAAM,CAG3B,GAAItD,EAAaF,EAAUwD,EAAgBhF,CAAG,EAC1C,OAAOgF,EAKX,GADAC,GAAmBL,EAAuB5E,EAAKgF,EAAgBrF,CAAU,EACrEsF,EAAkBF,EAGlB,OAAO,KAIXC,EAAiBA,EAAe,WACpC,CACJ,CACA,OAAOA,CACX,CAQA,SAASjD,EAAcpC,EAAY0B,EAAWG,EAAUD,EAAgBvB,EAAK,CAEzE,IAAIkF,EAAqB3D,EACrBX,EAAcY,EAAS,YACvB2D,EAAwB,EAE5B,KAAOD,GAAsB,MAAM,CAE/B,GAAIN,EAAuB5E,EAAKkF,EAAoBvF,CAAU,EAAI,EAG9D,OAAO,KAIX,GAAIuB,EAAYM,EAAU0D,CAAkB,EACxC,OAAOA,EAGX,GAAIhE,EAAYN,EAAasE,CAAkB,IAG3CC,IACAvE,EAAcA,EAAY,YAItBuE,GAAyB,GACzB,OAAO,KAKfD,EAAqBA,EAAmB,WAC5C,CAEA,OAAOA,CACX,CAEA,SAASrF,GAAaF,EAAY,CAC9B,IAAIyF,EAAS,IAAI,UAGbC,EAAyB1F,EAAW,QAAQ,uCAAwC,EAAE,EAG1F,GAAI0F,EAAuB,MAAM,UAAU,GAAKA,EAAuB,MAAM,UAAU,GAAKA,EAAuB,MAAM,UAAU,EAAG,CAClI,IAAIC,EAAUF,EAAO,gBAAgBzF,EAAY,WAAW,EAE5D,GAAI0F,EAAuB,MAAM,UAAU,EACvC,OAAAC,EAAQ,qBAAuB,GACxBA,EACJ,CAEH,IAAIC,EAAcD,EAAQ,WAC1B,OAAIC,GACAA,EAAY,qBAAuB,GAC5BA,GAEA,IAEf,CACJ,KAAO,CAIH,IAAID,EADcF,EAAO,gBAAgB,mBAAqBzF,EAAa,qBAAsB,WAAW,EAClF,KAAK,cAAc,UAAU,EAAE,QACzD,OAAA2F,EAAQ,qBAAuB,GACxBA,CACX,CACJ,CAEA,SAASvF,GAAiBJ,EAAY,CAClC,GAAIA,GAAc,KAGd,OADoB,SAAS,cAAc,KAAK,EAE7C,GAAIA,EAAW,qBAElB,OAAOA,EACJ,GAAIA,aAAsB,KAAM,CAEnC,IAAM6F,EAAc,SAAS,cAAc,KAAK,EAChD,OAAAA,EAAY,OAAO7F,CAAU,EACtB6F,CACX,KAAO,CAGH,IAAMA,EAAc,SAAS,cAAc,KAAK,EAChD,QAAWhG,IAAO,CAAC,GAAGG,CAAU,EAC5B6F,EAAY,OAAOhG,CAAG,EAE1B,OAAOgG,CACX,CACJ,CAEA,SAASzE,GAAeJ,EAAiBE,EAAaD,EAAa,CAC/D,IAAI6E,EAAQ,CAAC,EACTpC,EAAQ,CAAC,EACb,KAAO1C,GAAmB,MACtB8E,EAAM,KAAK9E,CAAe,EAC1BA,EAAkBA,EAAgB,gBAEtC,KAAO8E,EAAM,OAAS,GAAG,CACrB,IAAIC,EAAOD,EAAM,IAAI,EACrBpC,EAAM,KAAKqC,CAAI,EACf7E,EAAY,cAAc,aAAa6E,EAAM7E,CAAW,CAC5D,CAEA,IADAwC,EAAM,KAAKxC,CAAW,EACfD,GAAe,MAClB6E,EAAM,KAAK7E,CAAW,EACtByC,EAAM,KAAKzC,CAAW,EACtBA,EAAcA,EAAY,YAE9B,KAAO6E,EAAM,OAAS,GAClB5E,EAAY,cAAc,aAAa4E,EAAM,IAAI,EAAG5E,EAAY,WAAW,EAE/E,OAAOwC,CACX,CAEA,SAAS3C,GAAkBf,EAAYD,EAASM,EAAK,CACjD,IAAI2F,EACJA,EAAiBhG,EAAW,WAC5B,IAAIiG,EAAcD,EACdE,EAAQ,EACZ,KAAOF,GAAgB,CACnB,IAAIG,EAAWC,GAAaJ,EAAgBjG,EAASM,CAAG,EACpD8F,EAAWD,IACXD,EAAcD,EACdE,EAAQC,GAEZH,EAAiBA,EAAe,WACpC,CACA,OAAOC,CACX,CAEA,SAASG,GAAarB,EAAOC,EAAO3E,EAAK,CACrC,OAAIkB,EAAYwD,EAAOC,CAAK,EACjB,GAAKC,EAAuB5E,EAAK0E,EAAOC,CAAK,EAEjD,CACX,CAEA,SAAS1C,EAAWD,EAAUhC,EAAK,CAC/ByB,EAA2BzB,EAAKgC,CAAQ,EACpChC,EAAI,UAAU,kBAAkBgC,CAAQ,IAAM,KAElDA,EAAS,OAAO,EAChBhC,EAAI,UAAU,iBAAiBgC,CAAQ,EAC3C,CAMA,SAASgE,GAAoBhG,EAAKiG,EAAI,CAClC,MAAO,CAACjG,EAAI,QAAQ,IAAIiG,CAAE,CAC9B,CAEA,SAASC,GAAelG,EAAKiG,EAAIE,EAAY,CAEzC,OADYnG,EAAI,MAAM,IAAImG,CAAU,GAAK9G,GAC5B,IAAI4G,CAAE,CACvB,CAEA,SAASxE,EAA2BzB,EAAK0F,EAAM,CAC3C,IAAIU,EAAQpG,EAAI,MAAM,IAAI0F,CAAI,GAAKrG,EACnC,QAAW4G,KAAMG,EACbpG,EAAI,QAAQ,IAAIiG,CAAE,CAE1B,CAEA,SAASrB,EAAuB5E,EAAK0E,EAAOC,EAAO,CAC/C,IAAI0B,EAAYrG,EAAI,MAAM,IAAI0E,CAAK,GAAKrF,EACpCiH,EAAa,EACjB,QAAWL,KAAMI,EAGTL,GAAoBhG,EAAKiG,CAAE,GAAKC,GAAelG,EAAKiG,EAAItB,CAAK,GAC7D,EAAE2B,EAGV,OAAOA,CACX,CAUA,SAASC,EAAqBb,EAAMc,EAAO,CACvC,IAAIC,EAAaf,EAAK,cAElBgB,EAAahB,EAAK,iBAAiB,MAAM,EAC7C,QAAWlG,KAAOkH,EAAY,CAC1B,IAAIC,EAAUnH,EAGd,KAAOmH,IAAYF,GAAcE,GAAW,MAAM,CAC9C,IAAIP,EAAQI,EAAM,IAAIG,CAAO,EAEzBP,GAAS,OACTA,EAAQ,IAAI,IACZI,EAAM,IAAIG,EAASP,CAAK,GAE5BA,EAAM,IAAI5G,EAAI,EAAE,EAChBmH,EAAUA,EAAQ,aACtB,CACJ,CACJ,CAYA,SAASlC,GAAYmC,EAAYjH,EAAY,CACzC,IAAI6G,EAAQ,IAAI,IAChB,OAAAD,EAAqBK,EAAYJ,CAAK,EACtCD,EAAqB5G,EAAY6G,CAAK,EAC/BA,CACX,CAKA,MAAO,CACH,MAAA/G,EACA,SAAAH,CACJ,CACJ,EAAG,EC50BP,IAAIuH,EACAC,EAAS,EAEPC,GAAa,eAEnB,SAASC,EAAUC,EAAM,CACvB,OAAOA,EAAK,WAAa,KAAK,YAChC,CAEA,SAASC,GAAiBD,EAAM,CAC9B,OAAKD,EAAUC,CAAI,EAEjBA,EAAK,aAAaE,EAAO,uBAAuB,GAChDF,EAAK,aAAaE,EAAO,uBAAuB,IAAM,QAH3B,EAK/B,CAEA,SAASC,GAASH,EAAM,CACtB,OAAKD,EAAUC,CAAI,EACZA,IAAS,SAAS,cADI,EAE/B,CAEA,SAASI,GAAaJ,EAAM,CAE1B,MADI,EAAAC,GAAiBD,CAAI,GACrBG,GAASH,CAAI,GAAKA,EAAK,QAAQ,MAAMF,EAAU,EAErD,CAEA,IAAMO,EAAiB,CACrB,UAAW,CAAE,kBAAmB,CAACC,EAASC,IAAaH,GAAaE,CAAO,CAAE,EAC7E,WAAY,YACZ,kBAAmB,GACnB,KAAM,CAAE,MAAO,OAAQ,CACzB,EAEA,SAASE,GAAMC,EAASC,EAAMC,EAAU,CAAC,EAAG,CAC1C,IAAMC,EAAYC,IAAA,GAAKR,EAAe,WAAcM,EAAQ,WAC5D,OAAAA,EAAUG,EAAAD,IAAA,GAAKR,GAAmBM,GAAxB,CAAiC,UAAAC,CAAU,GAE9C,IAAI,QAAQG,GAAW,CAC5B,WAAW,IAAM,CACfC,EAAU,MAAMP,EAASC,EAAMC,CAAO,EACtCI,EAAQ,CACV,EAAGlB,CAAM,CACX,CAAC,CACH,CAEAD,EAAUY,GAEV,IAAOS,EAAQ,CACb,IAAI,OAAQ,CACV,OAAOpB,CACT,EAEA,IAAI,MAAMqB,EAAI,CACZrB,EAASqB,CACX,EAEA,IAAI,QAAS,CACX,OAAOtB,CACT,EAEA,IAAI,OAAOuB,EAAI,CACbvB,EAAUuB,CACZ,CACF,EClEA,IAAMC,EAAe,CACnB,OAAQ,mCACR,MAAO,kCACP,OAAQ,kCACV,EAGA,SAASC,EAAiBC,EAAUC,EAAQC,EAAU,CACpD,GAAM,CAAE,OAAAC,EAAQ,OAAAC,CAAO,EAAIJ,EAC3BC,EAASA,GAAU,CAAC,EACpBA,EAASI,EAAAC,EAAA,GAAKL,GAAL,CAAa,OAAQD,EAAS,MAAO,GAC9C,IAAMO,EAAU,CAAE,OAAAN,EAAQ,QAAS,EAAK,EAExCG,EAAO,cAAc,IAAI,YAAYN,EAAa,OAAQS,CAAO,CAAC,EAIlE,GAAI,CAAE,MAAAC,CAAM,EAAIP,EAAO,QAAU,CAAC,EAClCO,EAAQA,GAAS,EAEjB,IAAMC,EAAU,IAAM,CACpB,IAAMC,EAASR,EAASC,CAAM,EAC9BI,EAAQ,OAAO,OAASG,EACxBN,EAAO,cAAc,IAAI,YAAYN,EAAa,MAAOS,CAAO,CAAC,EAEjE,IAAII,EACAD,aAAkB,YAAWC,EAAUD,EAAO,UAC9CA,aAAkB,UAASC,EAAUD,GAErCC,EACFA,EACG,KAAK,IAAM,CACVJ,EAAQ,OAAO,QAAU,YACzBH,EAAO,cAAc,IAAI,YAAYN,EAAa,OAAQS,CAAO,CAAC,CACpE,CAAC,EACA,MAAMK,GAAS,CACdL,EAAQ,OAAO,QAAU,WACzBA,EAAQ,OAAO,MAAQK,EACvBR,EAAO,cAAc,IAAI,YAAYN,EAAa,OAAQS,CAAO,CAAC,CACpE,CAAC,EACAH,EAAO,cAAc,IAAI,YAAYN,EAAa,OAAQS,CAAO,CAAC,CACzE,EAEIC,EAAQ,EAAG,WAAWC,EAASD,CAAK,EACnCC,EAAQ,CACf,CAEA,SAASI,GAAoBC,EAAQC,EAAMC,EAAW,CACpD,IAAMC,EAAYF,EAAK,CAAC,EAClBG,EAAeH,EAAK,CAAC,EACrBd,EAAS,CAAE,OAAAa,EAAQ,UAAAG,EAAW,aAAAC,CAAa,EACjDF,EAAU,QAAQhB,GAChBD,EAAiBC,EAAUC,EAAQE,GACjCA,EAAO,cAAc,IAAI,YAAYc,EAAWC,CAAY,CAAC,CAC/D,CACF,CACF,CAEA,SAASC,GAAYL,EAAQC,EAAMC,EAAW,CAC5C,IAAMI,EAAOL,EAAK,CAAC,EACbd,EAAS,CAAE,OAAAa,EAAQ,KAAAM,CAAK,EAC9BJ,EAAU,QAAQhB,GAAYD,EAAiBC,EAAUC,EAAQE,GAAUkB,EAAM,OAAOlB,EAAQiB,CAAI,CAAC,CAAC,CACxG,CAEA,SAASE,GAAiBR,EAAQC,EAAMC,EAAW,CACjD,IAAMO,EAAWT,EAAO,MAAM,EAAG,EAAE,EAAE,KAAK,EACpCU,EAAQT,EAAK,CAAC,EACdd,EAAS,CAAE,OAAAa,EAAQ,SAAAS,EAAU,MAAAC,CAAM,EACzCR,EAAU,QAAQhB,GAAYD,EAAiBC,EAAUC,EAAQE,GAAWA,EAAOoB,CAAQ,EAAIC,CAAM,CAAC,CACxG,CAEA,SAASC,GAAaX,EAAQC,EAAMC,EAAW,CAC7C,IAAMf,EAAS,CAAE,OAAAa,EAAQ,KAAAC,CAAK,EAC9BC,EAAU,QAAQhB,GAChBD,EAAiBC,EAAUC,EAAQE,GAAUA,EAAOW,CAAM,EAAE,MAAMX,EAAQY,CAAI,CAAC,CACjF,CACF,CAGA,SAASW,EAAcZ,EAAQC,EAAMC,EAAW,CAE9C,OAAIF,EAAO,MAAM,oBAAoB,EAAUD,GAAoBC,EAAQC,EAAMC,CAAS,EAGtFF,EAAO,MAAM,gBAAgB,EAAUK,GAAYL,EAAQC,EAAMC,CAAS,EAG1EF,EAAO,SAAS,GAAG,EAAUQ,GAAiBR,EAAQC,EAAMC,CAAS,EAGlES,GAAaX,EAAQC,EAAMC,CAAS,CAC7C,CAEA,SAASW,GAAS,CAChB,IAAMC,EAAU,KAAK,MAAM,KAAK,gBAAgB,WAAW,EACrD,CAAE,GAAAC,EAAI,SAAAC,EAAU,SAAA9B,EAAU,OAAAc,EAAQ,KAAAC,EAAM,MAAAP,CAAM,EAAIoB,EACpDZ,EAAY,CAAC,CAAE,OAAQ,KAAM,OAAQ,IAAK,CAAC,EAC3Cc,IACFd,EAAY,MAAM,KAAK,SAAS,iBAAiBc,CAAQ,CAAC,EAAE,IAAIC,IAAO,CACrE,OAAQA,EACR,OAAQA,CACV,EAAE,GAEA/B,IACFgB,EAAYA,EAAU,IAAIgB,GAAK,CAC7B,GAAI,CAAE,OAAA7B,EAAQ,OAAAC,CAAO,EAAI4B,EACnBC,EAAQjC,EAAS,MAAM,GAAG,EAChC,KAAOiC,EAAM,OAAS,GACpB9B,EAASA,EAAO8B,EAAM,MAAM,CAAC,EACzB9B,EAAO,gBAAeC,EAASD,GAErC,MAAO,CAAE,OAAAA,EAAQ,OAAAC,CAAO,CAC1B,CAAC,GAGCI,EAAQ,EAAG,WAAW,IAAMkB,EAAcZ,EAAQC,EAAMC,CAAS,EAAGR,CAAK,EACxEkB,EAAcZ,EAAQC,EAAMC,CAAS,CAC5C,CClHA,GAAI,CAAC,KAAK,MACR,MAAM,IAAI,MACR,sHACF,EAEF,GAAI,CAAC,MAAM,cACT,MAAM,IAAI,MACR,oGACF,EAEF,MAAM,cAAc,OAASkB,EAC7B,KAAK,WAAa,KAAK,YAAc,CAAC,EACtC,KAAK,WAAW,QAAU,CAAE,OAAAA,EAAQ,aAAAC,EAAc,MAAAC,EAAO,OAAAC,EAAQ,QAAAC,CAAQ,EAEzE,QAAQ,KAAK,oFAAoF,EAEjG,IAAOC,GAAQ,KAAK,WAAW",
6
+ "names": ["version_default", "schema", "schema_default", "__spreadValues", "Idiomorph", "EMPTY_SET", "defaults", "noOp", "elt", "morph", "oldNode", "newContent", "config", "parseContent", "normalizedContent", "normalizeContent", "ctx", "createMorphContext", "morphNormalizedContent", "normalizedNewContent", "oldHead", "newHead", "promises", "handleHeadElement", "morphChildren", "bestMatch", "findBestNodeMatch", "previousSibling", "nextSibling", "morphedNode", "morphOldNodeTo", "insertSiblings", "ignoreValueOfActiveElement", "possibleActiveElement", "isSoftMatch", "syncNodeFrom", "newParent", "oldParent", "nextNewChild", "insertionPoint", "newChild", "removeIdsFromConsideration", "isIdSetMatch", "idSetMatch", "findIdSetMatch", "removeNodesBetween", "softMatch", "findSoftMatch", "tempNode", "removeNode", "ignoreAttribute", "attr", "to", "updateType", "from", "type", "fromAttributes", "toAttributes", "fromAttribute", "i", "toAttribute", "syncInputValue", "syncBooleanAttribute", "attributeName", "ignoreUpdate", "fromValue", "toValue", "newHeadTag", "currentHead", "added", "removed", "preserved", "nodesToAppend", "headMergeStyle", "srcToNewHeadNodes", "newHeadChild", "currentHeadElt", "inNewContent", "isReAppended", "isPreserved", "newNode", "newElt", "resolve", "promise", "_resolve", "removedElement", "log", "mergeDefaults", "finalConfig", "createIdMap", "node1", "node2", "getIdIntersectionCount", "startInclusive", "endExclusive", "newChildPotentialIdCount", "potentialMatch", "otherMatchCount", "potentialSoftMatch", "siblingSoftMatchCount", "parser", "contentWithSvgsRemoved", "content", "htmlElement", "dummyParent", "stack", "node", "currentElement", "bestElement", "score", "newScore", "scoreElement", "isIdInConsideration", "id", "idIsWithinNode", "targetNode", "idSet", "sourceSet", "matchCount", "populateIdMapForNode", "idMap", "nodeParent", "idElements", "current", "oldContent", "_method", "_delay", "trixEditor", "isElement", "node", "isTurboPermanent", "schema_default", "isActive", "morphAllowed", "defaultOptions", "oldNode", "_newNode", "morph", "element", "html", "options", "callbacks", "__spreadValues", "__spreadProps", "resolve", "Idiomorph", "morph_default", "ms", "fn", "invokeEvents", "withInvokeEvents", "receiver", "detail", "callback", "object", "target", "__spreadProps", "__spreadValues", "options", "delay", "execute", "result", "promise", "error", "invokeDispatchEvent", "method", "args", "receivers", "eventName", "eventOptions", "invokeMorph", "html", "morph_default", "invokeAssignment", "property", "value", "invokeMethod", "performInvoke", "invoke", "payload", "id", "selector", "el", "r", "chain", "invoke", "invokeEvents", "morph_default", "schema_default", "version_default", "javascript_default"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"app/javascript/version.js":{"bytes":24,"imports":[],"format":"esm"},"app/javascript/schema.js":{"bytes":99,"imports":[{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"node_modules/idiomorph/dist/idiomorph.esm.js":{"bytes":37490,"imports":[],"format":"esm"},"app/javascript/morph.js":{"bytes":1081,"imports":[{"path":"node_modules/idiomorph/dist/idiomorph.esm.js","kind":"import-statement","original":"idiomorph"},{"path":"app/javascript/schema.js","kind":"import-statement","original":"./schema"}],"format":"esm"},"app/javascript/invoke.js":{"bytes":4229,"imports":[{"path":"app/javascript/morph.js","kind":"import-statement","original":"./morph"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/index.js":{"bytes":720,"imports":[{"path":"app/javascript/version.js","kind":"import-statement","original":"./version"},{"path":"app/javascript/schema.js","kind":"import-statement","original":"./schema"},{"path":"app/javascript/invoke.js","kind":"import-statement","original":"./invoke"}],"format":"esm"}},"outputs":{"app/assets/builds/@turbo-boost/streams.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":61623},"app/assets/builds/@turbo-boost/streams.js":{"imports":[],"exports":["default"],"entryPoint":"app/javascript/index.js","inputs":{"app/javascript/version.js":{"bytesInOutput":15},"app/javascript/schema.js":{"bytesInOutput":67},"node_modules/idiomorph/dist/idiomorph.esm.js":{"bytesInOutput":7334},"app/javascript/morph.js":{"bytesInOutput":480},"app/javascript/invoke.js":{"bytesInOutput":1679},"app/javascript/index.js":{"bytesInOutput":557}},"bytes":10630}}}
1
+ {"inputs":{"app/javascript/version.js":{"bytes":24,"imports":[],"format":"esm"},"app/javascript/schema.js":{"bytes":99,"imports":[{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"node_modules/idiomorph/dist/idiomorph.esm.js":{"bytes":37490,"imports":[],"format":"esm"},"app/javascript/morph.js":{"bytes":1394,"imports":[{"path":"node_modules/idiomorph/dist/idiomorph.esm.js","kind":"import-statement","original":"idiomorph"},{"path":"app/javascript/schema.js","kind":"import-statement","original":"./schema"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/invoke.js":{"bytes":4297,"imports":[{"path":"app/javascript/morph.js","kind":"import-statement","original":"./morph"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/index.js":{"bytes":755,"imports":[{"path":"app/javascript/version.js","kind":"import-statement","original":"./version"},{"path":"app/javascript/schema.js","kind":"import-statement","original":"./schema"},{"path":"app/javascript/morph.js","kind":"import-statement","original":"./morph"},{"path":"app/javascript/invoke.js","kind":"import-statement","original":"./invoke"}],"format":"esm"}},"outputs":{"app/assets/builds/@turbo-boost/streams.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":62796},"app/assets/builds/@turbo-boost/streams.js":{"imports":[],"exports":["default"],"entryPoint":"app/javascript/index.js","inputs":{"app/javascript/version.js":{"bytesInOutput":15},"app/javascript/schema.js":{"bytesInOutput":67},"node_modules/idiomorph/dist/idiomorph.esm.js":{"bytesInOutput":7342},"app/javascript/morph.js":{"bytesInOutput":688},"app/javascript/invoke.js":{"bytesInOutput":1709},"app/javascript/index.js":{"bytesInOutput":565}},"bytes":10884}}}
@@ -1,5 +1,6 @@
1
1
  import VERSION from './version'
2
2
  import schema from './schema'
3
+ import morph from './morph'
3
4
  import { invoke, invokeEvents } from './invoke'
4
5
 
5
6
  if (!self['Turbo'])
@@ -14,7 +15,7 @@ if (!Turbo['StreamActions'])
14
15
 
15
16
  Turbo.StreamActions.invoke = invoke
16
17
  self.TurboBoost = self.TurboBoost || {}
17
- self.TurboBoost.Streams = { invoke, invokeEvents, schema, VERSION }
18
+ self.TurboBoost.Streams = { invoke, invokeEvents, morph, schema, VERSION }
18
19
 
19
20
  console.info('@turbo-boost/streams has initialized and registered new stream actions with Turbo.')
20
21
 
@@ -1,6 +1,6 @@
1
1
  import morph from './morph'
2
2
 
3
- export const invokeEvents = {
3
+ const invokeEvents = {
4
4
  before: 'turbo-boost:stream:before-invoke',
5
5
  after: 'turbo-boost:stream:after-invoke',
6
6
  finish: 'turbo-boost:stream:finish-invoke'
@@ -30,16 +30,16 @@ function withInvokeEvents(receiver, detail, callback) {
30
30
  if (result instanceof Promise) promise = result
31
31
 
32
32
  if (promise)
33
- promise.then(
34
- () => {
33
+ promise
34
+ .then(() => {
35
35
  options.detail.promise = 'fulfilled'
36
36
  target.dispatchEvent(new CustomEvent(invokeEvents.finish, options))
37
- },
38
- () => {
37
+ })
38
+ .catch(error => {
39
39
  options.detail.promise = 'rejected'
40
+ options.detail.error = error
40
41
  target.dispatchEvent(new CustomEvent(invokeEvents.finish, options))
41
- }
42
- )
42
+ })
43
43
  else target.dispatchEvent(new CustomEvent(invokeEvents.finish, options))
44
44
  }
45
45
 
@@ -61,7 +61,7 @@ function invokeDispatchEvent(method, args, receivers) {
61
61
  function invokeMorph(method, args, receivers) {
62
62
  const html = args[0]
63
63
  const detail = { method, html }
64
- receivers.forEach(receiver => withInvokeEvents(receiver, detail, object => morph(object, html)))
64
+ receivers.forEach(receiver => withInvokeEvents(receiver, detail, object => morph.method(object, html)))
65
65
  }
66
66
 
67
67
  function invokeAssignment(method, args, receivers) {
@@ -93,7 +93,7 @@ function performInvoke(method, args, receivers) {
93
93
  return invokeMethod(method, args, receivers)
94
94
  }
95
95
 
96
- export function invoke() {
96
+ function invoke() {
97
97
  const payload = JSON.parse(this.templateContent.textContent)
98
98
  const { id, selector, receiver, method, args, delay } = payload
99
99
  let receivers = [{ object: self, target: self }]
@@ -118,3 +118,5 @@ export function invoke() {
118
118
  if (delay > 0) setTimeout(() => performInvoke(method, args, receivers), delay)
119
119
  else performInvoke(method, args, receivers)
120
120
  }
121
+
122
+ export { invoke, invokeEvents }
@@ -1,36 +1,69 @@
1
1
  import { Idiomorph } from 'idiomorph'
2
2
  import schema from './schema'
3
3
 
4
- const input = /INPUT/i
5
- const inputTypes = /date|datetime-local|email|month|number|password|range|search|tel|text|time|url|week/i
6
- const textarea = /TEXTAREA/i
4
+ let _method
5
+ let _delay = 0
6
+
7
7
  const trixEditor = /TRIX-EDITOR/i
8
8
 
9
- const morphAllowed = node => {
10
- if (node.nodeType !== Node.ELEMENT_NODE) return true
11
- if (node !== document.activeElement) return true
9
+ function isElement(node) {
10
+ return node.nodeType === Node.ELEMENT_NODE
11
+ }
12
12
 
13
- // don't morph elements marked as turbo permanent
14
- if (
13
+ function isTurboPermanent(node) {
14
+ if (!isElement(node)) return false
15
+ return (
15
16
  node.hasAttribute(schema.turboPermanentAttribute) &&
16
17
  node.getAttribute(schema.turboPermanentAttribute) !== 'false'
17
18
  )
18
- return false
19
+ }
19
20
 
20
- // don't morph active textarea
21
- if (node.tagName.match(textarea)) return false
21
+ function isActive(node) {
22
+ if (!isElement(node)) return false
23
+ return node === document.activeElement
24
+ }
22
25
 
23
- // don't morph active trix-editor
24
- if (node.tagName.match(trixEditor)) return false
26
+ function morphAllowed(node) {
27
+ if (isTurboPermanent(node)) return false
28
+ if (isActive(node) && node.tagName.match(trixEditor)) return false
29
+ return true
30
+ }
25
31
 
26
- // don't morph active inputs
27
- return node.tagName.match(input) && node.getAttribute('type').match(inputTypes)
32
+ const defaultOptions = {
33
+ callbacks: { beforeNodeMorphed: (oldNode, _newNode) => morphAllowed(oldNode) },
34
+ morphStyle: 'outerHTML',
35
+ ignoreActiveValue: true,
36
+ head: { style: 'merge' }
28
37
  }
29
38
 
30
- const callbacks = {
31
- beforeNodeMorphed: (oldNode, _newNode) => morphAllowed(oldNode)
39
+ function morph(element, html, options = {}) {
40
+ const callbacks = { ...defaultOptions.callbacks, ...options.callbacks }
41
+ options = { ...defaultOptions, ...options, callbacks }
42
+
43
+ return new Promise(resolve => {
44
+ setTimeout(() => {
45
+ Idiomorph.morph(element, html, options)
46
+ resolve()
47
+ }, _delay)
48
+ })
32
49
  }
33
50
 
34
- const morph = (element, html) => Idiomorph.morph(element, html, { callbacks })
51
+ _method = morph
52
+
53
+ export default {
54
+ get delay() {
55
+ return _delay
56
+ },
57
+
58
+ set delay(ms) {
59
+ _delay = ms
60
+ },
35
61
 
36
- export default morph
62
+ get method() {
63
+ return _method
64
+ },
65
+
66
+ set method(fn) {
67
+ _method = fn
68
+ }
69
+ }
@@ -1 +1 @@
1
- export default '0.1.10'
1
+ export default '0.1.11'
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TurboBoost
4
4
  module Streams
5
- VERSION = "0.1.10"
5
+ VERSION = "0.1.11"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turbo_boost-streams
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
4
+ version: 0.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nate Hopkins (hopsoft)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-15 00:00:00.000000000 Z
11
+ date: 2024-02-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails