turbo_boost-streams 0.1.10 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
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": "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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", "_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