katalyst-kpop 4.0.0 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c4fd1aee213d132edf3577efecbc1f3e9503753a545af8cf734235f0d9992ea0
|
|
4
|
+
data.tar.gz: 92507a2dbf8bd77f5a075687f944acb4dfab278a8e767905ee1303e5ac73d409
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 916cef4ba176e3ac8ccbadca46011fc238029f767ea6d5d52d4961fd9453c1a36d6079ced7b2975a76e97acbde5920e06d084d3c211d12f2eca204682a5959c3
|
|
7
|
+
data.tar.gz: 81d567cf5ef19ea49e7b28d018fc2c57438c472c643af40df7961f4c83ddc4439ebbbe3e9ef76864fd33fb524cf7320964d08de70c24083d8ca1bb5d1b367136
|
|
@@ -295,7 +295,7 @@ class Kpop__FrameController extends Controller {
|
|
|
295
295
|
this.debug("event:clear", reason);
|
|
296
296
|
|
|
297
297
|
// clear the src from the frame (if any)
|
|
298
|
-
this.element.src = "";
|
|
298
|
+
if (this.modal?.src === this.element.src) this.element.src = "";
|
|
299
299
|
this.element.innerHTML = "";
|
|
300
300
|
|
|
301
301
|
// mark the modal as hidden
|
|
@@ -295,7 +295,7 @@ class Kpop__FrameController extends Controller {
|
|
|
295
295
|
this.debug("event:clear", reason);
|
|
296
296
|
|
|
297
297
|
// clear the src from the frame (if any)
|
|
298
|
-
this.element.src = "";
|
|
298
|
+
if (this.modal?.src === this.element.src) this.element.src = "";
|
|
299
299
|
this.element.innerHTML = "";
|
|
300
300
|
|
|
301
301
|
// mark the modal as hidden
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Controller as e}from"@hotwired/stimulus";import{Turbo as t}from"@hotwired/turbo-rails";let s=!1;const i=function(e){return s?console.debug.bind(console,"[%s] %s",e):n},n=()=>{};Object.defineProperty(i,"enabled",{get:function(){return s},set:function(e){s=e}});class r{constructor(e,t,s=null){this.frame=e,this.element=t,this.uri=new URL(s||t.dataset.src,window.location.origin)}connect(){this.element.addEventListener("cancel",this.cancel),this.element.addEventListener("close",this.close),this.element.addEventListener("mousedown",this.scrim)}disconnect(){this.element.removeEventListener("cancel",this.cancel),this.element.removeEventListener("close",this.close),this.element.removeEventListener("mousedown",this.scrim)}get src(){return this.uri.pathname+this.uri.search+this.uri.hash}cancel=e=>{this.debug("event:cancel",e),e.preventDefault(),this.frame.dismiss({animate:!0,reason:"dialog:cancel"})};close=e=>{this.debug("event:close",e),this.frame.clear({reason:"dialog:close"})};scrim=e=>{"DIALOG"===e.target.tagName&&(this.debug("event:scrim",e),this.frame.dismiss({animate:!0,reason:"dialog:scrim"}))};async open({animate:e=!0}={}){this.debug("open-start",e),await a(this.element,e,()=>this.element.showModal()),this.debug("open-end")}async dismiss({animate:e=!0}={}){this.debug("dismiss-start",e),await a(this.element,e,()=>this.element.removeAttribute("open")),this.debug("dismiss-end"),this.element.close()}beforeVisit(e,t){this.debug("before-visit",t.detail.url),this.frame.clear()}static get debug(){return i(this.name)}get debug(){return i(this.constructor.name)}}function a(e,t,s){if(!t)return s();const i=function(e,t="0.2s"){const s=getComputedStyle(e).getPropertyValue("--animation-duration")||t,i=parseFloat(s);return s.endsWith("ms")?i:1e3*i}(e);return new Promise(n=>{const r=()=>{e.removeEventListener("animationend",r,{once:!0}),clearTimeout(a),e.toggleAttribute("animate",!1),n()};e.addEventListener("animationend",r,{once:!0});const a=setTimeout(r,i);e.toggleAttribute("animate",t),s()})}class o extends r{static connect(e,t){e.open(new o(e,t),{animate:!1})}}class c extends r{static connect(e,t,s){return this.debug("restore",s),e.open(new c(e,t,s),{animate:!1})}static load(e,t,s){return this.debug("load",s),e.open(new c(e,t,s),{animate:!0})}static visit(e,t,s,i){s.hasAttribute("busy")&&(this.debug("clearing src to cancel turbo request"),s.src=""),this.debug("navigate to",e),i()}}class d extends e{static values={open:Boolean};connect(){this.debug("connect",this.element.src),this.element.kpop=this,function(e){const t=e.element.delegate.constructor.prototype;if(t._linkClickIntercepted)return;t._linkClickIntercepted=t.linkClickIntercepted,t.linkClickIntercepted=function(e,s){const i=e?.getAttribute("data-turbo-frame")||this.element.getAttribute("target");let n=document.getElementById(i);n instanceof Turbo.FrameElement||(n=this.element),n.kpop?(n.kpop.debug("navigate-frame %s => %s",n.src,s),c.visit(s,n.kpop,n,()=>{t._linkClickIntercepted.call(this,e,s)})):t._linkClickIntercepted.call(this,e,s)}}(this);const e=this.element.querySelector("dialog");this.element.src&&e?(this.debug("new frame modal",this.element.src),c.connect(this,e,this.element.src).then(()=>{})):e?(this.debug("new content modal",e),o.connect(this,e)):(this.debug("no modal"),this.clear())}disconnect(){this.debug("disconnect",this.element.src),delete this.element.kpop,delete this.modal}openValueChanged(e){this.debug("open-changed",e)}async open(e,{animate:t=!0}={}){return this.isOpen?(this.debug("skip open as already open"),this.modal||=e,!1):(await this.dismissing,this.opening||=Promise.resolve().then(()=>(e.connect(),this.#e(e,{animate:t}))))}async dismiss({animate:e=!0,reason:t=""}={}){return this.debug("event:dismiss",t),this.isOpen?(await this.opening,this.dismissing||=this.#t({animate:e,reason:t})):(this.debug("skip dismiss as already closed"),!1)}clear({reason:e=""}={}){this.debug("event:clear",e),this.element.src="",this.element.innerHTML="",this.openValue=!1,this.modal&&this.modal.disconnect(),delete this.modal,delete this.dismissing}beforeFrameRender(e){this.debug("before-frame-render",e.detail.newFrame.baseURI),e.detail.newFrame.id===this.element.id&&(e.preventDefault(),this.dismiss({animate:!0,reason:"before-frame-render"}).then(()=>{this.debug("resume-frame-render",e.detail.newFrame.baseURI),e.detail.resume()}))}beforeStreamRender(e){this.debug("before-stream-render",e.detail);const t=e.detail.render;e.detail.render=async e=>{await this.dismissing,this.debug("stream-render",e),await t(e)}}beforeVisit(e){if(this.debug("before-visit",e.detail.url),e.detail.url===this.element.src)return;if("/resume_historical_location"===new URL(e.detail.url.toString(),document.baseURI).pathname)return e.preventDefault(),this.dismiss();this.isOpen&&this.modal.beforeVisit(this,e)}frameLoad(e){this.debug("frame-load"),c.load(this,e.target.firstElementChild,e.target.src).then(()=>{})}beforeFetchRequest(){const e=document.activeElement;e===document.body?delete this.lastFetchFocusRef:this.lastFetchFocusRef=new WeakRef(e)}get isOpen(){return this.openValue&&!this.dismissing}async#e(e,{animate:t=!0}={}){var s;return this.debug("open-start",{animate:t}),this.previousFocusRef=document.activeElement===document.body?this.lastFetchFocusRef:new WeakRef(document.activeElement),this.debug("capture focus",this.previousFocusRef?.deref()),this.modal=e,this.openValue=!0,this.element.delegate.sourceURL=this.modal.src,await e.open({animate:t}),delete this.opening,this.debug("open-end"),(s=this.modal?.element,s?s.querySelector("[autofocus]")??s.querySelector("button:not([disabled])"):null)?.focus(),Turbo.session.view.forceReloaded&&console.error("Turbo-Frame response is incompatible with current page"),!0}async#t({animate:e=!0,reason:t=""}={}){this.debug("dismiss-start",{animate:e,reason:t}),this.element.isConnected?(this.modal||console.warn("modal missing on dismiss"),await(this.modal?.dismiss({animate:e})),this.clear(),this.previousFocusRef?.deref()?.focus(),this.debug("restore focus",this.previousFocusRef?.deref()),delete this.previousFocusRef,this.debug("dismiss-end")):this.debug("skip dismiss, element detached")}async#s(e){return new Promise(window.requestAnimationFrame).then(e)}get debug(){return i("FrameController")}}class u{started=!1;constructor(e,t){this.delegate=e,this.eventTarget=t}start(){this.started||("loading"===this.eventTarget.readyState?this.eventTarget.addEventListener("DOMContentLoaded",this.#i,{once:!0}):this.#i())}stop(){this.started&&(this.eventTarget.removeEventListener("mouseenter",this.#n,{capture:!0,passive:!0}),this.eventTarget.removeEventListener("turbo:before-prefetch",this.#n,{capture:!0,passive:!0}),this.eventTarget.removeEventListener("focusin",this.#n,{capture:!0,passive:!0}),this.eventTarget.removeEventListener("mouseleave",this.#r,{capture:!0,passive:!0}),this.eventTarget.removeEventListener("focusout",this.#r,{capture:!0,passive:!0}),this.started=!1)}#i=()=>{this.started||(this.started=!0,this.eventTarget.addEventListener("mouseenter",this.#n,{capture:!0,passive:!0}),this.eventTarget.addEventListener("focusin",this.#n,{capture:!0,passive:!0}),this.eventTarget.addEventListener("turbo:before-prefetch",this.#n,{capture:!0,passive:!0}),this.eventTarget.addEventListener("mouseleave",this.#r,{capture:!0,passive:!0}),this.eventTarget.addEventListener("focusout",this.#r,{capture:!0,passive:!0}))};#n=e=>{const t=e.target;if(t.matches&&t.matches("a[href]:not([target^=_]):not([download]):not([data-turbo-frame]")&&this.#a(t)){const e=t,s=function(e){return new URL(e.getAttribute("href").toString(),document.baseURI)}(e);this.delegate.isModalLink(e,s)&&(e.dataset.turboFrame="kpop")}};#r=e=>{const t=e.target;t.matches&&t.matches("a[href][data-turbo-frame='kpop']")&&delete t.dataset.turboFrame};#a(e){return!!e.getAttribute("href")&&(!h(e)&&(!l(e)&&(!m(e)&&!p(e))))}}const h=e=>e.origin!==document.location.origin||!["http:","https:"].includes(e.protocol)||e.hasAttribute("target"),l=e=>e.pathname+e.search===document.location.pathname+document.location.search||e.href.startsWith("#"),m=e=>"false"===e.getAttribute("data-turbo"),p=e=>{const t=e.getAttribute("data-turbo-method");return!(!t||"get"===t.toLowerCase())||(!!g(e)||(!!e.hasAttribute("data-turbo-confirm")||!!e.hasAttribute("data-turbo-stream")))},g=e=>e.hasAttribute("data-remote")||e.hasAttribute("data-behavior")||e.hasAttribute("data-confirm")||e.hasAttribute("data-method");class b{constructor(e=[]){this.rules=[],e.forEach(e=>{this.#o(e)})}properties(e){return this.rules.reduce((t,s)=>s(e,t),{})}#o({patterns:e,properties:t}){e.forEach(e=>{this.rules.push(function(e,t){return(s,i)=>e.test(s.pathname)?{...i,...t}:i}(new RegExp(e),t))})}}class f extends r{static async open(e,t){const s=!e.isOpen;await e.dismiss({animate:s,reason:"turbo-stream.kpop_open"}),e.element.append(t.templateContent);const i=e.element.querySelector("dialog"),n=i.dataset.src;await e.open(new f(e,i,n),{animate:s})}}class v{start(){t.StreamActions.kpop_open=w}stop(){delete t.StreamActions.kpop_open}}function w(){const e=this.targetElements[0]?.kpop;e&&f.open(e,this).then(()=>{})}const L=[{identifier:"kpop--frame",controllerConstructor:d}];class k{static configure(e={}){return this.instance||=new this(e),i.enabled=this.instance.debug,this.instance}constructor({rules:e=[],debug:t=!1}={}){this.config={rules:e,debug:t},this.ruleset=new b(e),this.linkObserver=new u(this,document),this.streamActions=new v}start(){return this.streamActions.start(),this.linkObserver.start(),window.addEventListener("turbo:before-fetch-request",R),this.debug&&(document.addEventListener("focusin",E),document.addEventListener("focusout",A)),this}stop(){window.removeEventListener("turbo:before-fetch-request",R),document.removeEventListener("focusin",E),document.removeEventListener("focusout",A),this.streamActions.stop(),this.linkObserver.stop()}isModalLink(e,t){return"modal"===this.ruleset.properties(t).context}get debug(){return Boolean(this.config.debug)}}const E=e=>i("Application")("focus",e.target),A=e=>i("Application")("blur",e.target),R=e=>{const t=e.detail.fetchOptions.headers;t.Accept?.includes("text/vnd.turbo-stream.html")&&(t["Kpop-Available"]="true")};export{L as controllers,k as default};
|
|
1
|
+
import{Controller as e}from"@hotwired/stimulus";import{Turbo as t}from"@hotwired/turbo-rails";let s=!1;const i=function(e){return s?console.debug.bind(console,"[%s] %s",e):n},n=()=>{};Object.defineProperty(i,"enabled",{get:function(){return s},set:function(e){s=e}});class r{constructor(e,t,s=null){this.frame=e,this.element=t,this.uri=new URL(s||t.dataset.src,window.location.origin)}connect(){this.element.addEventListener("cancel",this.cancel),this.element.addEventListener("close",this.close),this.element.addEventListener("mousedown",this.scrim)}disconnect(){this.element.removeEventListener("cancel",this.cancel),this.element.removeEventListener("close",this.close),this.element.removeEventListener("mousedown",this.scrim)}get src(){return this.uri.pathname+this.uri.search+this.uri.hash}cancel=e=>{this.debug("event:cancel",e),e.preventDefault(),this.frame.dismiss({animate:!0,reason:"dialog:cancel"})};close=e=>{this.debug("event:close",e),this.frame.clear({reason:"dialog:close"})};scrim=e=>{"DIALOG"===e.target.tagName&&(this.debug("event:scrim",e),this.frame.dismiss({animate:!0,reason:"dialog:scrim"}))};async open({animate:e=!0}={}){this.debug("open-start",e),await a(this.element,e,()=>this.element.showModal()),this.debug("open-end")}async dismiss({animate:e=!0}={}){this.debug("dismiss-start",e),await a(this.element,e,()=>this.element.removeAttribute("open")),this.debug("dismiss-end"),this.element.close()}beforeVisit(e,t){this.debug("before-visit",t.detail.url),this.frame.clear()}static get debug(){return i(this.name)}get debug(){return i(this.constructor.name)}}function a(e,t,s){if(!t)return s();const i=function(e,t="0.2s"){const s=getComputedStyle(e).getPropertyValue("--animation-duration")||t,i=parseFloat(s);return s.endsWith("ms")?i:1e3*i}(e);return new Promise(n=>{const r=()=>{e.removeEventListener("animationend",r,{once:!0}),clearTimeout(a),e.toggleAttribute("animate",!1),n()};e.addEventListener("animationend",r,{once:!0});const a=setTimeout(r,i);e.toggleAttribute("animate",t),s()})}class o extends r{static connect(e,t){e.open(new o(e,t),{animate:!1})}}class c extends r{static connect(e,t,s){return this.debug("restore",s),e.open(new c(e,t,s),{animate:!1})}static load(e,t,s){return this.debug("load",s),e.open(new c(e,t,s),{animate:!0})}static visit(e,t,s,i){s.hasAttribute("busy")&&(this.debug("clearing src to cancel turbo request"),s.src=""),this.debug("navigate to",e),i()}}class d extends e{static values={open:Boolean};connect(){this.debug("connect",this.element.src),this.element.kpop=this,function(e){const t=e.element.delegate.constructor.prototype;if(t._linkClickIntercepted)return;t._linkClickIntercepted=t.linkClickIntercepted,t.linkClickIntercepted=function(e,s){const i=e?.getAttribute("data-turbo-frame")||this.element.getAttribute("target");let n=document.getElementById(i);n instanceof Turbo.FrameElement||(n=this.element),n.kpop?(n.kpop.debug("navigate-frame %s => %s",n.src,s),c.visit(s,n.kpop,n,()=>{t._linkClickIntercepted.call(this,e,s)})):t._linkClickIntercepted.call(this,e,s)}}(this);const e=this.element.querySelector("dialog");this.element.src&&e?(this.debug("new frame modal",this.element.src),c.connect(this,e,this.element.src).then(()=>{})):e?(this.debug("new content modal",e),o.connect(this,e)):(this.debug("no modal"),this.clear())}disconnect(){this.debug("disconnect",this.element.src),delete this.element.kpop,delete this.modal}openValueChanged(e){this.debug("open-changed",e)}async open(e,{animate:t=!0}={}){return this.isOpen?(this.debug("skip open as already open"),this.modal||=e,!1):(await this.dismissing,this.opening||=Promise.resolve().then(()=>(e.connect(),this.#e(e,{animate:t}))))}async dismiss({animate:e=!0,reason:t=""}={}){return this.debug("event:dismiss",t),this.isOpen?(await this.opening,this.dismissing||=this.#t({animate:e,reason:t})):(this.debug("skip dismiss as already closed"),!1)}clear({reason:e=""}={}){this.debug("event:clear",e),this.modal?.src===this.element.src&&(this.element.src=""),this.element.innerHTML="",this.openValue=!1,this.modal&&this.modal.disconnect(),delete this.modal,delete this.dismissing}beforeFrameRender(e){this.debug("before-frame-render",e.detail.newFrame.baseURI),e.detail.newFrame.id===this.element.id&&(e.preventDefault(),this.dismiss({animate:!0,reason:"before-frame-render"}).then(()=>{this.debug("resume-frame-render",e.detail.newFrame.baseURI),e.detail.resume()}))}beforeStreamRender(e){this.debug("before-stream-render",e.detail);const t=e.detail.render;e.detail.render=async e=>{await this.dismissing,this.debug("stream-render",e),await t(e)}}beforeVisit(e){if(this.debug("before-visit",e.detail.url),e.detail.url===this.element.src)return;if("/resume_historical_location"===new URL(e.detail.url.toString(),document.baseURI).pathname)return e.preventDefault(),this.dismiss();this.isOpen&&this.modal.beforeVisit(this,e)}frameLoad(e){this.debug("frame-load"),c.load(this,e.target.firstElementChild,e.target.src).then(()=>{})}beforeFetchRequest(){const e=document.activeElement;e===document.body?delete this.lastFetchFocusRef:this.lastFetchFocusRef=new WeakRef(e)}get isOpen(){return this.openValue&&!this.dismissing}async#e(e,{animate:t=!0}={}){var s;return this.debug("open-start",{animate:t}),this.previousFocusRef=document.activeElement===document.body?this.lastFetchFocusRef:new WeakRef(document.activeElement),this.debug("capture focus",this.previousFocusRef?.deref()),this.modal=e,this.openValue=!0,this.element.delegate.sourceURL=this.modal.src,await e.open({animate:t}),delete this.opening,this.debug("open-end"),(s=this.modal?.element,s?s.querySelector("[autofocus]")??s.querySelector("button:not([disabled])"):null)?.focus(),Turbo.session.view.forceReloaded&&console.error("Turbo-Frame response is incompatible with current page"),!0}async#t({animate:e=!0,reason:t=""}={}){this.debug("dismiss-start",{animate:e,reason:t}),this.element.isConnected?(this.modal||console.warn("modal missing on dismiss"),await(this.modal?.dismiss({animate:e})),this.clear(),this.previousFocusRef?.deref()?.focus(),this.debug("restore focus",this.previousFocusRef?.deref()),delete this.previousFocusRef,this.debug("dismiss-end")):this.debug("skip dismiss, element detached")}async#s(e){return new Promise(window.requestAnimationFrame).then(e)}get debug(){return i("FrameController")}}class u{started=!1;constructor(e,t){this.delegate=e,this.eventTarget=t}start(){this.started||("loading"===this.eventTarget.readyState?this.eventTarget.addEventListener("DOMContentLoaded",this.#i,{once:!0}):this.#i())}stop(){this.started&&(this.eventTarget.removeEventListener("mouseenter",this.#n,{capture:!0,passive:!0}),this.eventTarget.removeEventListener("turbo:before-prefetch",this.#n,{capture:!0,passive:!0}),this.eventTarget.removeEventListener("focusin",this.#n,{capture:!0,passive:!0}),this.eventTarget.removeEventListener("mouseleave",this.#r,{capture:!0,passive:!0}),this.eventTarget.removeEventListener("focusout",this.#r,{capture:!0,passive:!0}),this.started=!1)}#i=()=>{this.started||(this.started=!0,this.eventTarget.addEventListener("mouseenter",this.#n,{capture:!0,passive:!0}),this.eventTarget.addEventListener("focusin",this.#n,{capture:!0,passive:!0}),this.eventTarget.addEventListener("turbo:before-prefetch",this.#n,{capture:!0,passive:!0}),this.eventTarget.addEventListener("mouseleave",this.#r,{capture:!0,passive:!0}),this.eventTarget.addEventListener("focusout",this.#r,{capture:!0,passive:!0}))};#n=e=>{const t=e.target;if(t.matches&&t.matches("a[href]:not([target^=_]):not([download]):not([data-turbo-frame]")&&this.#a(t)){const e=t,s=function(e){return new URL(e.getAttribute("href").toString(),document.baseURI)}(e);this.delegate.isModalLink(e,s)&&(e.dataset.turboFrame="kpop")}};#r=e=>{const t=e.target;t.matches&&t.matches("a[href][data-turbo-frame='kpop']")&&delete t.dataset.turboFrame};#a(e){return!!e.getAttribute("href")&&(!h(e)&&(!l(e)&&(!m(e)&&!p(e))))}}const h=e=>e.origin!==document.location.origin||!["http:","https:"].includes(e.protocol)||e.hasAttribute("target"),l=e=>e.pathname+e.search===document.location.pathname+document.location.search||e.href.startsWith("#"),m=e=>"false"===e.getAttribute("data-turbo"),p=e=>{const t=e.getAttribute("data-turbo-method");return!(!t||"get"===t.toLowerCase())||(!!g(e)||(!!e.hasAttribute("data-turbo-confirm")||!!e.hasAttribute("data-turbo-stream")))},g=e=>e.hasAttribute("data-remote")||e.hasAttribute("data-behavior")||e.hasAttribute("data-confirm")||e.hasAttribute("data-method");class b{constructor(e=[]){this.rules=[],e.forEach(e=>{this.#o(e)})}properties(e){return this.rules.reduce((t,s)=>s(e,t),{})}#o({patterns:e,properties:t}){e.forEach(e=>{this.rules.push(function(e,t){return(s,i)=>e.test(s.pathname)?{...i,...t}:i}(new RegExp(e),t))})}}class f extends r{static async open(e,t){const s=!e.isOpen;await e.dismiss({animate:s,reason:"turbo-stream.kpop_open"}),e.element.append(t.templateContent);const i=e.element.querySelector("dialog"),n=i.dataset.src;await e.open(new f(e,i,n),{animate:s})}}class v{start(){t.StreamActions.kpop_open=w}stop(){delete t.StreamActions.kpop_open}}function w(){const e=this.targetElements[0]?.kpop;e&&f.open(e,this).then(()=>{})}const L=[{identifier:"kpop--frame",controllerConstructor:d}];class k{static configure(e={}){return this.instance||=new this(e),i.enabled=this.instance.debug,this.instance}constructor({rules:e=[],debug:t=!1}={}){this.config={rules:e,debug:t},this.ruleset=new b(e),this.linkObserver=new u(this,document),this.streamActions=new v}start(){return this.streamActions.start(),this.linkObserver.start(),window.addEventListener("turbo:before-fetch-request",R),this.debug&&(document.addEventListener("focusin",E),document.addEventListener("focusout",A)),this}stop(){window.removeEventListener("turbo:before-fetch-request",R),document.removeEventListener("focusin",E),document.removeEventListener("focusout",A),this.streamActions.stop(),this.linkObserver.stop()}isModalLink(e,t){return"modal"===this.ruleset.properties(t).context}get debug(){return Boolean(this.config.debug)}}const E=e=>i("Application")("focus",e.target),A=e=>i("Application")("blur",e.target),R=e=>{const t=e.detail.fetchOptions.headers;t.Accept?.includes("text/vnd.turbo-stream.html")&&(t["Kpop-Available"]="true")};export{L as controllers,k as default};
|
|
2
2
|
//# sourceMappingURL=kpop.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kpop.min.js","sources":["../../../javascript/kpop/utils/debug.js","../../../javascript/kpop/modals/modal.js","../../../javascript/kpop/modals/content_modal.js","../../../javascript/kpop/modals/frame_modal.js","../../../javascript/kpop/controllers/frame_controller.js","../../../javascript/kpop/utils/link_observer.js","../../../javascript/kpop/utils/ruleset.js","../../../javascript/kpop/modals/stream_modal.js","../../../javascript/kpop/utils/stream_actions.js","../../../javascript/kpop/application.js"],"sourcesContent":["let enabled = false;\n\nconst debug = function (receiver) {\n if (enabled) {\n return console.debug.bind(console, \"[%s] %s\", receiver);\n } else {\n return noop;\n }\n};\n\nconst noop = () => {};\n\nObject.defineProperty(debug, \"enabled\", {\n get: function () {\n return enabled;\n },\n set: function (debug) {\n enabled = debug;\n },\n});\n\nexport default debug;\n","import debug from \"../utils/debug\";\n\nexport class Modal {\n constructor(frame, dialog, src = null) {\n this.frame = frame;\n this.element = dialog;\n this.uri = new URL(src || dialog.dataset.src, window.location.origin);\n }\n\n connect() {\n this.element.addEventListener(\"cancel\", this.cancel);\n this.element.addEventListener(\"close\", this.close);\n this.element.addEventListener(\"mousedown\", this.scrim);\n }\n\n disconnect() {\n this.element.removeEventListener(\"cancel\", this.cancel);\n this.element.removeEventListener(\"close\", this.close);\n this.element.removeEventListener(\"mousedown\", this.scrim);\n }\n\n get src() {\n return this.uri.pathname + this.uri.search + this.uri.hash;\n }\n\n cancel = (e) => {\n this.debug(\"event:cancel\", e);\n\n e.preventDefault();\n\n this.frame.dismiss({ animate: true, reason: \"dialog:cancel\" });\n };\n\n close = (e) => {\n this.debug(\"event:close\", e);\n\n this.frame.clear({ reason: \"dialog:close\" });\n };\n\n scrim = (e) => {\n if (e.target.tagName === \"DIALOG\") {\n this.debug(\"event:scrim\", e);\n\n this.frame.dismiss({ animate: true, reason: \"dialog:scrim\" });\n }\n };\n\n async open({ animate = true } = {}) {\n this.debug(\"open-start\", animate);\n\n await animation(this.element, animate, () => this.element.showModal());\n\n this.debug(\"open-end\");\n }\n\n /**\n * Modals are closed by animating out the modal then removing the modal\n * element from the wrapping frame.\n *\n * @returns {Promise<void>}\n */\n async dismiss({ animate = true } = {}) {\n this.debug(\"dismiss-start\", animate);\n\n await animation(this.element, animate, () =>\n this.element.removeAttribute(\"open\"),\n );\n\n this.debug(\"dismiss-end\");\n\n this.element.close();\n }\n\n /**\n * When user navigates from inside a modal, dismiss the modal first so\n * that the modal does not appear in the history stack.\n *\n * @param frame FrameController\n * @param e Turbo navigation event\n */\n beforeVisit(frame, e) {\n this.debug(`before-visit`, e.detail.url);\n\n this.frame.clear();\n }\n\n static get debug() {\n return debug(this.name);\n }\n\n get debug() {\n return debug(this.constructor.name);\n }\n}\n\nfunction animation(el, animate, trigger) {\n if (!animate) return trigger();\n\n const duration = animationDuration(el);\n\n return new Promise((resolve) => {\n const resolver = () => {\n el.removeEventListener(\"animationend\", resolver, { once: true });\n clearTimeout(timeout);\n el.toggleAttribute(\"animate\", false);\n resolve();\n };\n\n el.addEventListener(\"animationend\", resolver, { once: true });\n const timeout = setTimeout(resolver, duration);\n\n el.toggleAttribute(\"animate\", animate);\n trigger();\n });\n}\n\nfunction animationDuration(el, defaultValue = \"0.2s\") {\n const value =\n getComputedStyle(el).getPropertyValue(\"--animation-duration\") ||\n defaultValue;\n const num = parseFloat(value);\n if (value.endsWith(\"ms\")) return num;\n return num * 1000;\n}\n","import { Modal } from \"./modal\";\n\nexport class ContentModal extends Modal {\n static connect(frame, dialog) {\n frame.open(new ContentModal(frame, dialog), { animate: false });\n }\n}\n","import { Modal } from \"./modal\";\n\nexport class FrameModal extends Modal {\n /**\n * When the FrameController detects a frame element on connect, it runs this\n * method to sanity check the frame src and restore the modal state.\n *\n * @param {Kpop__FrameController} frame\n * @param {HTMLDialogElement} dialog\n * @param {String} src\n */\n static connect(frame, dialog, src) {\n // restoration visit\n this.debug(\"restore\", src);\n return frame.open(new FrameModal(frame, dialog, src), { animate: false });\n }\n\n /**\n * When the FrameController detects a frame load event, it runs this\n * method to open the modal.\n *\n * @param {Kpop__FrameController} frame\n * @param {HTMLDialogElement} dialog\n * @param {String} src\n */\n static load(frame, dialog, src) {\n this.debug(\"load\", src);\n return frame.open(new FrameModal(frame, dialog, src), { animate: true });\n }\n\n /**\n * When a user clicks a kpop link, turbo intercepts the click and calls\n * #navigateFrame on the turbo frame controller before setting the TurboFrame\n * element's src attribute. KPOP intercepts this call and calls this method\n * first so we cancel problematic navigations that might cache invalid states.\n *\n * @param location URL requested by turbo\n * @param frame FrameController\n * @param element TurboFrame element\n * @param resolve continuation chain\n */\n static visit(location, frame, element, resolve) {\n // Ensure that turbo doesn't cache the frame in a loading state by cancelling\n // the current request (if any) by clearing the src.\n // Known issue: this won't work if the frame was previously rendering a useful src.\n if (element.hasAttribute(\"busy\")) {\n this.debug(\"clearing src to cancel turbo request\");\n element.src = \"\";\n }\n\n this.debug(\"navigate to\", location);\n resolve();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nimport { ContentModal } from \"../modals/content_modal\";\nimport { FrameModal } from \"../modals/frame_modal\";\n\nimport debug from \"../utils/debug\";\n\nexport default class Kpop__FrameController extends Controller {\n static values = {\n open: Boolean,\n };\n\n connect() {\n this.debug(\"connect\", this.element.src);\n\n this.element.kpop = this;\n\n // allow our code to intercept frame navigation requests before dom changes\n installNavigationInterception(this);\n\n const dialog = this.element.querySelector(\"dialog\");\n\n if (this.element.src && dialog) {\n this.debug(\"new frame modal\", this.element.src);\n FrameModal.connect(this, dialog, this.element.src).then(() => {});\n } else if (dialog) {\n this.debug(\"new content modal\", dialog);\n ContentModal.connect(this, dialog);\n } else {\n this.debug(\"no modal\");\n this.clear();\n }\n }\n\n disconnect() {\n this.debug(\"disconnect\", this.element.src);\n\n delete this.element.kpop;\n delete this.modal;\n }\n\n openValueChanged(open) {\n this.debug(\"open-changed\", open);\n }\n\n /**\n * Animate an attached modal into the foreground. Returns a promise that\n * resolves when the animation is complete.\n *\n * @param modal\n * @param animate\n * @returns {Promise<Boolean>}\n */\n async open(modal, { animate = true } = {}) {\n if (this.isOpen) {\n this.debug(\"skip open as already open\");\n this.modal ||= modal;\n return false;\n }\n\n await this.dismissing;\n\n return (this.opening ||= Promise.resolve().then(() => {\n modal.connect();\n return this.#open(modal, { animate });\n }));\n }\n\n /**\n * Cause a modal to hide. Returns a promise that will resolve when the\n * animation (if requested) is finished.\n *\n * If the modal is already animating out, returns the existing promise instead.\n *\n * @param {Boolean} animate\n * @param {String} reason\n * @returns {Promise}\n */\n async dismiss({ animate = true, reason = \"\" } = {}) {\n this.debug(\"event:dismiss\", reason);\n\n if (!this.isOpen) {\n this.debug(\"skip dismiss as already closed\");\n return false;\n }\n\n await this.opening;\n\n return (this.dismissing ||= this.#dismiss({ animate, reason }));\n }\n\n /**\n * Clean up after a modal is finished dismissing.\n */\n clear({ reason = \"\" } = {}) {\n this.debug(\"event:clear\", reason);\n\n // clear the src from the frame (if any)\n this.element.src = \"\";\n this.element.innerHTML = \"\";\n\n // mark the modal as hidden\n this.openValue = false;\n\n // unset modal\n if (this.modal) this.modal.disconnect();\n delete this.modal;\n delete this.dismissing;\n }\n\n // EVENTS\n\n /**\n * Incoming frame render, dismiss the current modal (if any) first.\n *\n * We're starting the actual visit\n *\n * @param event turbo:before-render\n */\n beforeFrameRender(event) {\n this.debug(\"before-frame-render\", event.detail.newFrame.baseURI);\n\n if (event.detail.newFrame.id !== this.element.id) return;\n\n event.preventDefault();\n\n this.dismiss({ animate: true, reason: \"before-frame-render\" }).then(() => {\n this.debug(\"resume-frame-render\", event.detail.newFrame.baseURI);\n event.detail.resume();\n });\n }\n\n beforeStreamRender(event) {\n this.debug(\"before-stream-render\", event.detail);\n\n const resume = event.detail.render;\n\n // Defer rendering until dismiss is complete.\n // Dismiss may change history so we need to wait for it to complete to avoid\n // losing DOM changes on restoration visits.\n event.detail.render = async (stream) => {\n await this.dismissing;\n\n this.debug(\"stream-render\", stream);\n\n await resume(stream);\n };\n }\n\n beforeVisit(e) {\n this.debug(\"before-visit\", e.detail.url);\n\n // ignore visits to the current frame, these fire when the frame navigates\n if (e.detail.url === this.element.src) return;\n\n const url = new URL(e.detail.url.toString(), document.baseURI);\n if (url.pathname === \"/resume_historical_location\") {\n e.preventDefault();\n return this.dismiss();\n }\n\n // ignore unless we're open\n if (!this.isOpen) return;\n\n this.modal.beforeVisit(this, e);\n }\n\n frameLoad(e) {\n this.debug(\"frame-load\");\n\n FrameModal.load(this, e.target.firstElementChild, e.target.src).then(\n () => {},\n );\n }\n\n /**\n * Outgoing fetch request. Capture the initiator so we can return focus if it causes a modal to show.\n */\n beforeFetchRequest() {\n const focusElement = document.activeElement;\n\n if (focusElement === document.body) {\n delete this.lastFetchFocusRef;\n } else {\n this.lastFetchFocusRef = new WeakRef(focusElement);\n }\n }\n\n get isOpen() {\n return this.openValue && !this.dismissing;\n }\n\n async #open(modal, { animate = true } = {}) {\n this.debug(\"open-start\", { animate });\n\n this.previousFocusRef =\n document.activeElement === document.body\n ? this.lastFetchFocusRef\n : new WeakRef(document.activeElement);\n this.debug(\"capture focus\", this.previousFocusRef?.deref());\n\n this.modal = modal;\n this.openValue = true;\n\n // Set turbo-frame[src] without causing a load event\n this.element.delegate.sourceURL = this.modal.src;\n\n await modal.open({ animate });\n\n delete this.opening;\n\n this.debug(\"open-end\");\n\n autofocus(this.modal?.element)?.focus();\n\n // Detect https://github.com/hotwired/turbo-rails/issues/580\n if (Turbo.session.view.forceReloaded) {\n console.error(\"Turbo-Frame response is incompatible with current page\");\n }\n\n return true;\n }\n\n async #dismiss({ animate = true, reason = \"\" } = {}) {\n this.debug(\"dismiss-start\", { animate, reason });\n\n // if this element is detached then we've experienced a turbo navigation\n if (!this.element.isConnected) {\n this.debug(\"skip dismiss, element detached\");\n return;\n }\n\n if (!this.modal) {\n console.warn(\"modal missing on dismiss\");\n }\n\n await this.modal?.dismiss({ animate });\n\n this.clear();\n\n this.previousFocusRef?.deref()?.focus();\n this.debug(\"restore focus\", this.previousFocusRef?.deref());\n delete this.previousFocusRef;\n\n this.debug(\"dismiss-end\");\n }\n\n async #nextFrame(callback) {\n return new Promise(window.requestAnimationFrame).then(callback);\n }\n\n get debug() {\n return debug(\"FrameController\");\n }\n}\n\n/**\n * Monkey patch for Turbo#FrameController.\n *\n * Intercept calls to linkClickIntercepted(element, location) and ensures\n * that src is cleared if the frame is busy so that we don't restore an\n * in-progress src on restoration visits.\n *\n * See Turbo issue: https://github.com/hotwired/turbo/issues/1055\n *\n * @param controller FrameController\n */\nfunction installNavigationInterception(controller) {\n const TurboFrameController =\n controller.element.delegate.constructor.prototype;\n\n if (TurboFrameController._linkClickIntercepted) return;\n\n TurboFrameController._linkClickIntercepted =\n TurboFrameController.linkClickIntercepted;\n TurboFrameController.linkClickIntercepted = function (element, location) {\n // #findFrameElement\n const id =\n element?.getAttribute(\"data-turbo-frame\") ||\n this.element.getAttribute(\"target\");\n let frame = document.getElementById(id);\n if (!(frame instanceof Turbo.FrameElement)) {\n frame = this.element;\n }\n\n if (frame.kpop) {\n frame.kpop.debug(\"navigate-frame %s => %s\", frame.src, location);\n FrameModal.visit(location, frame.kpop, frame, () => {\n TurboFrameController._linkClickIntercepted.call(\n this,\n element,\n location,\n );\n });\n } else {\n TurboFrameController._linkClickIntercepted.call(this, element, location);\n }\n };\n}\n\nfunction autofocus(container) {\n if (!container) return null;\n\n return (\n container.querySelector(\"[autofocus]\") ??\n container.querySelector(\"button:not([disabled])\")\n );\n}\n","/**\n * Based on Turbo's LinkObserver, checks links on mouse-over and focus to see\n * whether they should open in modals. If they should, then sets the\n * data-turbo-frame attribute so it will be prefetched and opened in the context\n * of the kpop turbo frame.\n */\nexport default class LinkObserver {\n started = false;\n\n constructor(delegate, eventTarget) {\n this.delegate = delegate;\n this.eventTarget = eventTarget;\n }\n\n start() {\n if (this.started) return;\n if (this.eventTarget.readyState === \"loading\") {\n this.eventTarget.addEventListener(\"DOMContentLoaded\", this.#enable, {\n once: true,\n });\n } else {\n this.#enable();\n }\n }\n\n stop() {\n if (!this.started) return;\n this.eventTarget.removeEventListener(\"mouseenter\", this.#addKpopLink, {\n capture: true,\n passive: true,\n });\n this.eventTarget.removeEventListener(\n \"turbo:before-prefetch\",\n this.#addKpopLink,\n {\n capture: true,\n passive: true,\n },\n );\n this.eventTarget.removeEventListener(\"focusin\", this.#addKpopLink, {\n capture: true,\n passive: true,\n });\n this.eventTarget.removeEventListener(\"mouseleave\", this.#removeKpopLink, {\n capture: true,\n passive: true,\n });\n this.eventTarget.removeEventListener(\"focusout\", this.#removeKpopLink, {\n capture: true,\n passive: true,\n });\n this.started = false;\n }\n\n #enable = () => {\n if (this.started) return;\n this.started = true;\n this.eventTarget.addEventListener(\"mouseenter\", this.#addKpopLink, {\n capture: true,\n passive: true,\n });\n this.eventTarget.addEventListener(\"focusin\", this.#addKpopLink, {\n capture: true,\n passive: true,\n });\n this.eventTarget.addEventListener(\n \"turbo:before-prefetch\",\n this.#addKpopLink,\n {\n capture: true,\n passive: true,\n },\n );\n this.eventTarget.addEventListener(\"mouseleave\", this.#removeKpopLink, {\n capture: true,\n passive: true,\n });\n this.eventTarget.addEventListener(\"focusout\", this.#removeKpopLink, {\n capture: true,\n passive: true,\n });\n };\n\n #addKpopLink = (event) => {\n const target = event.target;\n const isLink =\n target.matches &&\n target.matches(\n \"a[href]:not([target^=_]):not([download]):not([data-turbo-frame]\",\n );\n if (isLink && this.#isPrefetchable(target)) {\n const link = target;\n const location = getLocationForLink(link);\n if (this.delegate.isModalLink(link, location)) {\n link.dataset.turboFrame = \"kpop\";\n }\n }\n };\n\n #removeKpopLink = (event) => {\n const target = event.target;\n const isLink =\n target.matches && target.matches(\"a[href][data-turbo-frame='kpop']\");\n if (isLink) {\n delete target.dataset.turboFrame;\n }\n };\n\n #isPrefetchable(link) {\n const href = link.getAttribute(\"href\");\n if (!href) return false;\n if (unfetchableLink(link)) return false;\n if (linkToTheSamePage(link)) return false;\n if (linkOptsOut(link)) return false;\n if (nonSafeLink(link)) return false;\n return true;\n }\n}\n\nfunction getLocationForLink(link) {\n return new URL(link.getAttribute(\"href\").toString(), document.baseURI);\n}\n\nconst unfetchableLink = (link) =>\n link.origin !== document.location.origin ||\n ![\"http:\", \"https:\"].includes(link.protocol) ||\n link.hasAttribute(\"target\");\n\nconst linkToTheSamePage = (link) =>\n link.pathname + link.search ===\n document.location.pathname + document.location.search ||\n link.href.startsWith(\"#\");\n\nconst linkOptsOut = (link) => {\n return link.getAttribute(\"data-turbo\") === \"false\";\n};\n\nconst nonSafeLink = (link) => {\n const turboMethod = link.getAttribute(\"data-turbo-method\");\n if (turboMethod && turboMethod.toLowerCase() !== \"get\") return true;\n if (isUJS(link)) return true;\n if (link.hasAttribute(\"data-turbo-confirm\")) return true;\n if (link.hasAttribute(\"data-turbo-stream\")) return true;\n return false;\n};\n\nconst isUJS = (link) =>\n link.hasAttribute(\"data-remote\") ||\n link.hasAttribute(\"data-behavior\") ||\n link.hasAttribute(\"data-confirm\") ||\n link.hasAttribute(\"data-method\");\n","/**\n * Similar to Hotwire's PathConfiguration.json, this class compiles a list of\n * rules to check link hrefs against so that we can identify links that\n * should open in a KPOP modal.\n *\n * Unlike Hotwire Native, we can't intercept 303s in the browser before they\n * load. Browser sandbox prevents us from inspecting the location of redirect\n * requests so we can only intercept links that match modals directly.\n *\n * For posts and redirects, we need server support (flash modals, streams).\n */\nexport default class Ruleset {\n constructor(rules = []) {\n this.rules = [];\n\n rules.forEach((rule) => {\n this.#compileRule(rule);\n });\n }\n\n /**\n * Returns properties for the given URL\n *\n * @param {URL} location\n * @returns {} properties\n */\n properties(location) {\n return this.rules.reduce((c, f) => f(location, c), {});\n }\n\n #compileRule({ patterns, properties }) {\n patterns.forEach((pattern) => {\n this.rules.push(locationMatcher(new RegExp(pattern), properties));\n });\n }\n}\n\nfunction locationMatcher(re, properties) {\n return (location, accumulator) =>\n re.test(location.pathname)\n ? { ...accumulator, ...properties }\n : accumulator;\n}\n","import { Modal } from \"./modal\";\n\nexport class StreamModal extends Modal {\n /**\n * When a turbo-stream[action=kpop_open] element is rendered, it runs this\n * method to load the modal template as a StreamModal.\n *\n * @param {Kpop__FrameController} frame\n * @param {Turbo.StreamElement} action\n */\n static async open(frame, action) {\n const animate = !frame.isOpen;\n\n await frame.dismiss({ animate, reason: \"turbo-stream.kpop_open\" });\n\n frame.element.append(action.templateContent);\n\n const dialog = frame.element.querySelector(\"dialog\");\n const src = dialog.dataset.src;\n\n await frame.open(new StreamModal(frame, dialog, src), { animate });\n }\n}\n","import { Turbo } from \"@hotwired/turbo-rails\";\n\nimport { StreamModal } from \"../modals/stream_modal\";\n\nexport default class StreamActions {\n start() {\n Turbo.StreamActions.kpop_open = openStreamModal;\n }\n\n stop() {\n delete Turbo.StreamActions.kpop_open;\n }\n}\n\nfunction openStreamModal() {\n const frame = this.targetElements[0]?.kpop;\n\n if (frame) {\n StreamModal.open(frame, this).then(() => {});\n }\n}\n","import FrameController from \"../kpop/controllers/frame_controller\";\n\nimport debug from \"./utils/debug\";\nimport LinkObserver from \"./utils/link_observer\";\nimport Ruleset from \"./utils/ruleset\";\nimport StreamActions from \"./utils/stream_actions\";\n\nexport const controllers = [\n { identifier: \"kpop--frame\", controllerConstructor: FrameController },\n];\n\nexport default class Application {\n static configure(config = {}) {\n this.instance ||= new this(config);\n debug.enabled = this.instance.debug;\n return this.instance;\n }\n\n constructor({ rules = [], debug = false } = {}) {\n this.config = { rules, debug };\n this.ruleset = new Ruleset(rules);\n this.linkObserver = new LinkObserver(this, document);\n this.streamActions = new StreamActions();\n }\n\n start() {\n this.streamActions.start();\n this.linkObserver.start();\n\n window.addEventListener(\n \"turbo:before-fetch-request\",\n addKpopToRequestHeaders,\n );\n\n if (this.debug) {\n document.addEventListener(\"focusin\", debugFocusIn);\n document.addEventListener(\"focusout\", debugFocusOut);\n }\n\n return this;\n }\n\n stop() {\n window.removeEventListener(\n \"turbo:before-fetch-request\",\n addKpopToRequestHeaders,\n );\n document.removeEventListener(\"focusin\", debugFocusIn);\n document.removeEventListener(\"focusout\", debugFocusOut);\n\n this.streamActions.stop();\n this.linkObserver.stop();\n }\n\n isModalLink(link, location) {\n const properties = this.ruleset.properties(location);\n return properties.context === \"modal\";\n }\n\n get debug() {\n return Boolean(this.config.debug);\n }\n}\n\nconst debugFocusIn = (e) => debug(\"Application\")(\"focus\", e.target);\nconst debugFocusOut = (e) => debug(\"Application\")(\"blur\", e.target);\n\nconst addKpopToRequestHeaders = (e) => {\n const headers = e.detail.fetchOptions.headers;\n\n if (headers[\"Accept\"]?.includes(\"text/vnd.turbo-stream.html\")) {\n headers[\"Kpop-Available\"] = \"true\";\n }\n};\n"],"names":["enabled","debug","receiver","console","bind","noop","Object","defineProperty","get","set","Modal","constructor","frame","dialog","src","this","element","uri","URL","dataset","window","location","origin","connect","addEventListener","cancel","close","scrim","disconnect","removeEventListener","pathname","search","hash","e","preventDefault","dismiss","animate","reason","clear","target","tagName","open","animation","showModal","removeAttribute","beforeVisit","detail","url","name","el","trigger","duration","defaultValue","value","getComputedStyle","getPropertyValue","num","parseFloat","endsWith","animationDuration","Promise","resolve","resolver","once","clearTimeout","timeout","toggleAttribute","setTimeout","ContentModal","FrameModal","load","visit","hasAttribute","Kpop__FrameController","Controller","static","Boolean","kpop","controller","TurboFrameController","delegate","prototype","_linkClickIntercepted","linkClickIntercepted","id","getAttribute","document","getElementById","Turbo","FrameElement","call","installNavigationInterception","querySelector","then","modal","openValueChanged","isOpen","dismissing","opening","innerHTML","openValue","beforeFrameRender","event","newFrame","baseURI","resume","beforeStreamRender","render","async","stream","toString","frameLoad","firstElementChild","beforeFetchRequest","focusElement","activeElement","body","lastFetchFocusRef","WeakRef","container","previousFocusRef","deref","sourceURL","focus","session","view","forceReloaded","error","isConnected","warn","nextFrame","callback","requestAnimationFrame","LinkObserver","started","eventTarget","start","readyState","enable","stop","addKpopLink","capture","passive","removeKpopLink","matches","isPrefetchable","link","getLocationForLink","isModalLink","turboFrame","unfetchableLink","linkToTheSamePage","linkOptsOut","nonSafeLink","includes","protocol","href","startsWith","turboMethod","toLowerCase","isUJS","Ruleset","rules","forEach","rule","compileRule","properties","reduce","c","f","patterns","pattern","push","re","accumulator","test","locationMatcher","RegExp","StreamModal","action","append","templateContent","StreamActions","kpop_open","openStreamModal","targetElements","controllers","identifier","controllerConstructor","FrameController","Application","configure","config","instance","ruleset","linkObserver","streamActions","addKpopToRequestHeaders","debugFocusIn","debugFocusOut","context","headers","fetchOptions"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"kpop.min.js","sources":["../../../javascript/kpop/utils/debug.js","../../../javascript/kpop/modals/modal.js","../../../javascript/kpop/modals/content_modal.js","../../../javascript/kpop/modals/frame_modal.js","../../../javascript/kpop/controllers/frame_controller.js","../../../javascript/kpop/utils/link_observer.js","../../../javascript/kpop/utils/ruleset.js","../../../javascript/kpop/modals/stream_modal.js","../../../javascript/kpop/utils/stream_actions.js","../../../javascript/kpop/application.js"],"sourcesContent":["let enabled = false;\n\nconst debug = function (receiver) {\n if (enabled) {\n return console.debug.bind(console, \"[%s] %s\", receiver);\n } else {\n return noop;\n }\n};\n\nconst noop = () => {};\n\nObject.defineProperty(debug, \"enabled\", {\n get: function () {\n return enabled;\n },\n set: function (debug) {\n enabled = debug;\n },\n});\n\nexport default debug;\n","import debug from \"../utils/debug\";\n\nexport class Modal {\n constructor(frame, dialog, src = null) {\n this.frame = frame;\n this.element = dialog;\n this.uri = new URL(src || dialog.dataset.src, window.location.origin);\n }\n\n connect() {\n this.element.addEventListener(\"cancel\", this.cancel);\n this.element.addEventListener(\"close\", this.close);\n this.element.addEventListener(\"mousedown\", this.scrim);\n }\n\n disconnect() {\n this.element.removeEventListener(\"cancel\", this.cancel);\n this.element.removeEventListener(\"close\", this.close);\n this.element.removeEventListener(\"mousedown\", this.scrim);\n }\n\n get src() {\n return this.uri.pathname + this.uri.search + this.uri.hash;\n }\n\n cancel = (e) => {\n this.debug(\"event:cancel\", e);\n\n e.preventDefault();\n\n this.frame.dismiss({ animate: true, reason: \"dialog:cancel\" });\n };\n\n close = (e) => {\n this.debug(\"event:close\", e);\n\n this.frame.clear({ reason: \"dialog:close\" });\n };\n\n scrim = (e) => {\n if (e.target.tagName === \"DIALOG\") {\n this.debug(\"event:scrim\", e);\n\n this.frame.dismiss({ animate: true, reason: \"dialog:scrim\" });\n }\n };\n\n async open({ animate = true } = {}) {\n this.debug(\"open-start\", animate);\n\n await animation(this.element, animate, () => this.element.showModal());\n\n this.debug(\"open-end\");\n }\n\n /**\n * Modals are closed by animating out the modal then removing the modal\n * element from the wrapping frame.\n *\n * @returns {Promise<void>}\n */\n async dismiss({ animate = true } = {}) {\n this.debug(\"dismiss-start\", animate);\n\n await animation(this.element, animate, () =>\n this.element.removeAttribute(\"open\"),\n );\n\n this.debug(\"dismiss-end\");\n\n this.element.close();\n }\n\n /**\n * When user navigates from inside a modal, dismiss the modal first so\n * that the modal does not appear in the history stack.\n *\n * @param frame FrameController\n * @param e Turbo navigation event\n */\n beforeVisit(frame, e) {\n this.debug(`before-visit`, e.detail.url);\n\n this.frame.clear();\n }\n\n static get debug() {\n return debug(this.name);\n }\n\n get debug() {\n return debug(this.constructor.name);\n }\n}\n\nfunction animation(el, animate, trigger) {\n if (!animate) return trigger();\n\n const duration = animationDuration(el);\n\n return new Promise((resolve) => {\n const resolver = () => {\n el.removeEventListener(\"animationend\", resolver, { once: true });\n clearTimeout(timeout);\n el.toggleAttribute(\"animate\", false);\n resolve();\n };\n\n el.addEventListener(\"animationend\", resolver, { once: true });\n const timeout = setTimeout(resolver, duration);\n\n el.toggleAttribute(\"animate\", animate);\n trigger();\n });\n}\n\nfunction animationDuration(el, defaultValue = \"0.2s\") {\n const value =\n getComputedStyle(el).getPropertyValue(\"--animation-duration\") ||\n defaultValue;\n const num = parseFloat(value);\n if (value.endsWith(\"ms\")) return num;\n return num * 1000;\n}\n","import { Modal } from \"./modal\";\n\nexport class ContentModal extends Modal {\n static connect(frame, dialog) {\n frame.open(new ContentModal(frame, dialog), { animate: false });\n }\n}\n","import { Modal } from \"./modal\";\n\nexport class FrameModal extends Modal {\n /**\n * When the FrameController detects a frame element on connect, it runs this\n * method to sanity check the frame src and restore the modal state.\n *\n * @param {Kpop__FrameController} frame\n * @param {HTMLDialogElement} dialog\n * @param {String} src\n */\n static connect(frame, dialog, src) {\n // restoration visit\n this.debug(\"restore\", src);\n return frame.open(new FrameModal(frame, dialog, src), { animate: false });\n }\n\n /**\n * When the FrameController detects a frame load event, it runs this\n * method to open the modal.\n *\n * @param {Kpop__FrameController} frame\n * @param {HTMLDialogElement} dialog\n * @param {String} src\n */\n static load(frame, dialog, src) {\n this.debug(\"load\", src);\n return frame.open(new FrameModal(frame, dialog, src), { animate: true });\n }\n\n /**\n * When a user clicks a kpop link, turbo intercepts the click and calls\n * #navigateFrame on the turbo frame controller before setting the TurboFrame\n * element's src attribute. KPOP intercepts this call and calls this method\n * first so we cancel problematic navigations that might cache invalid states.\n *\n * @param location URL requested by turbo\n * @param frame FrameController\n * @param element TurboFrame element\n * @param resolve continuation chain\n */\n static visit(location, frame, element, resolve) {\n // Ensure that turbo doesn't cache the frame in a loading state by cancelling\n // the current request (if any) by clearing the src.\n // Known issue: this won't work if the frame was previously rendering a useful src.\n if (element.hasAttribute(\"busy\")) {\n this.debug(\"clearing src to cancel turbo request\");\n element.src = \"\";\n }\n\n this.debug(\"navigate to\", location);\n resolve();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nimport { ContentModal } from \"../modals/content_modal\";\nimport { FrameModal } from \"../modals/frame_modal\";\n\nimport debug from \"../utils/debug\";\n\nexport default class Kpop__FrameController extends Controller {\n static values = {\n open: Boolean,\n };\n\n connect() {\n this.debug(\"connect\", this.element.src);\n\n this.element.kpop = this;\n\n // allow our code to intercept frame navigation requests before dom changes\n installNavigationInterception(this);\n\n const dialog = this.element.querySelector(\"dialog\");\n\n if (this.element.src && dialog) {\n this.debug(\"new frame modal\", this.element.src);\n FrameModal.connect(this, dialog, this.element.src).then(() => {});\n } else if (dialog) {\n this.debug(\"new content modal\", dialog);\n ContentModal.connect(this, dialog);\n } else {\n this.debug(\"no modal\");\n this.clear();\n }\n }\n\n disconnect() {\n this.debug(\"disconnect\", this.element.src);\n\n delete this.element.kpop;\n delete this.modal;\n }\n\n openValueChanged(open) {\n this.debug(\"open-changed\", open);\n }\n\n /**\n * Animate an attached modal into the foreground. Returns a promise that\n * resolves when the animation is complete.\n *\n * @param modal\n * @param animate\n * @returns {Promise<Boolean>}\n */\n async open(modal, { animate = true } = {}) {\n if (this.isOpen) {\n this.debug(\"skip open as already open\");\n this.modal ||= modal;\n return false;\n }\n\n await this.dismissing;\n\n return (this.opening ||= Promise.resolve().then(() => {\n modal.connect();\n return this.#open(modal, { animate });\n }));\n }\n\n /**\n * Cause a modal to hide. Returns a promise that will resolve when the\n * animation (if requested) is finished.\n *\n * If the modal is already animating out, returns the existing promise instead.\n *\n * @param {Boolean} animate\n * @param {String} reason\n * @returns {Promise}\n */\n async dismiss({ animate = true, reason = \"\" } = {}) {\n this.debug(\"event:dismiss\", reason);\n\n if (!this.isOpen) {\n this.debug(\"skip dismiss as already closed\");\n return false;\n }\n\n await this.opening;\n\n return (this.dismissing ||= this.#dismiss({ animate, reason }));\n }\n\n /**\n * Clean up after a modal is finished dismissing.\n */\n clear({ reason = \"\" } = {}) {\n this.debug(\"event:clear\", reason);\n\n // clear the src from the frame (if any)\n if (this.modal?.src === this.element.src) this.element.src = \"\";\n this.element.innerHTML = \"\";\n\n // mark the modal as hidden\n this.openValue = false;\n\n // unset modal\n if (this.modal) this.modal.disconnect();\n delete this.modal;\n delete this.dismissing;\n }\n\n // EVENTS\n\n /**\n * Incoming frame render, dismiss the current modal (if any) first.\n *\n * We're starting the actual visit\n *\n * @param event turbo:before-render\n */\n beforeFrameRender(event) {\n this.debug(\"before-frame-render\", event.detail.newFrame.baseURI);\n\n if (event.detail.newFrame.id !== this.element.id) return;\n\n event.preventDefault();\n\n this.dismiss({ animate: true, reason: \"before-frame-render\" }).then(() => {\n this.debug(\"resume-frame-render\", event.detail.newFrame.baseURI);\n event.detail.resume();\n });\n }\n\n beforeStreamRender(event) {\n this.debug(\"before-stream-render\", event.detail);\n\n const resume = event.detail.render;\n\n // Defer rendering until dismiss is complete.\n // Dismiss may change history so we need to wait for it to complete to avoid\n // losing DOM changes on restoration visits.\n event.detail.render = async (stream) => {\n await this.dismissing;\n\n this.debug(\"stream-render\", stream);\n\n await resume(stream);\n };\n }\n\n beforeVisit(e) {\n this.debug(\"before-visit\", e.detail.url);\n\n // ignore visits to the current frame, these fire when the frame navigates\n if (e.detail.url === this.element.src) return;\n\n const url = new URL(e.detail.url.toString(), document.baseURI);\n if (url.pathname === \"/resume_historical_location\") {\n e.preventDefault();\n return this.dismiss();\n }\n\n // ignore unless we're open\n if (!this.isOpen) return;\n\n this.modal.beforeVisit(this, e);\n }\n\n frameLoad(e) {\n this.debug(\"frame-load\");\n\n FrameModal.load(this, e.target.firstElementChild, e.target.src).then(\n () => {},\n );\n }\n\n /**\n * Outgoing fetch request. Capture the initiator so we can return focus if it causes a modal to show.\n */\n beforeFetchRequest() {\n const focusElement = document.activeElement;\n\n if (focusElement === document.body) {\n delete this.lastFetchFocusRef;\n } else {\n this.lastFetchFocusRef = new WeakRef(focusElement);\n }\n }\n\n get isOpen() {\n return this.openValue && !this.dismissing;\n }\n\n async #open(modal, { animate = true } = {}) {\n this.debug(\"open-start\", { animate });\n\n this.previousFocusRef =\n document.activeElement === document.body\n ? this.lastFetchFocusRef\n : new WeakRef(document.activeElement);\n this.debug(\"capture focus\", this.previousFocusRef?.deref());\n\n this.modal = modal;\n this.openValue = true;\n\n // Set turbo-frame[src] without causing a load event\n this.element.delegate.sourceURL = this.modal.src;\n\n await modal.open({ animate });\n\n delete this.opening;\n\n this.debug(\"open-end\");\n\n autofocus(this.modal?.element)?.focus();\n\n // Detect https://github.com/hotwired/turbo-rails/issues/580\n if (Turbo.session.view.forceReloaded) {\n console.error(\"Turbo-Frame response is incompatible with current page\");\n }\n\n return true;\n }\n\n async #dismiss({ animate = true, reason = \"\" } = {}) {\n this.debug(\"dismiss-start\", { animate, reason });\n\n // if this element is detached then we've experienced a turbo navigation\n if (!this.element.isConnected) {\n this.debug(\"skip dismiss, element detached\");\n return;\n }\n\n if (!this.modal) {\n console.warn(\"modal missing on dismiss\");\n }\n\n await this.modal?.dismiss({ animate });\n\n this.clear();\n\n this.previousFocusRef?.deref()?.focus();\n this.debug(\"restore focus\", this.previousFocusRef?.deref());\n delete this.previousFocusRef;\n\n this.debug(\"dismiss-end\");\n }\n\n async #nextFrame(callback) {\n return new Promise(window.requestAnimationFrame).then(callback);\n }\n\n get debug() {\n return debug(\"FrameController\");\n }\n}\n\n/**\n * Monkey patch for Turbo#FrameController.\n *\n * Intercept calls to linkClickIntercepted(element, location) and ensures\n * that src is cleared if the frame is busy so that we don't restore an\n * in-progress src on restoration visits.\n *\n * See Turbo issue: https://github.com/hotwired/turbo/issues/1055\n *\n * @param controller FrameController\n */\nfunction installNavigationInterception(controller) {\n const TurboFrameController =\n controller.element.delegate.constructor.prototype;\n\n if (TurboFrameController._linkClickIntercepted) return;\n\n TurboFrameController._linkClickIntercepted =\n TurboFrameController.linkClickIntercepted;\n TurboFrameController.linkClickIntercepted = function (element, location) {\n // #findFrameElement\n const id =\n element?.getAttribute(\"data-turbo-frame\") ||\n this.element.getAttribute(\"target\");\n let frame = document.getElementById(id);\n if (!(frame instanceof Turbo.FrameElement)) {\n frame = this.element;\n }\n\n if (frame.kpop) {\n frame.kpop.debug(\"navigate-frame %s => %s\", frame.src, location);\n FrameModal.visit(location, frame.kpop, frame, () => {\n TurboFrameController._linkClickIntercepted.call(\n this,\n element,\n location,\n );\n });\n } else {\n TurboFrameController._linkClickIntercepted.call(this, element, location);\n }\n };\n}\n\nfunction autofocus(container) {\n if (!container) return null;\n\n return (\n container.querySelector(\"[autofocus]\") ??\n container.querySelector(\"button:not([disabled])\")\n );\n}\n","/**\n * Based on Turbo's LinkObserver, checks links on mouse-over and focus to see\n * whether they should open in modals. If they should, then sets the\n * data-turbo-frame attribute so it will be prefetched and opened in the context\n * of the kpop turbo frame.\n */\nexport default class LinkObserver {\n started = false;\n\n constructor(delegate, eventTarget) {\n this.delegate = delegate;\n this.eventTarget = eventTarget;\n }\n\n start() {\n if (this.started) return;\n if (this.eventTarget.readyState === \"loading\") {\n this.eventTarget.addEventListener(\"DOMContentLoaded\", this.#enable, {\n once: true,\n });\n } else {\n this.#enable();\n }\n }\n\n stop() {\n if (!this.started) return;\n this.eventTarget.removeEventListener(\"mouseenter\", this.#addKpopLink, {\n capture: true,\n passive: true,\n });\n this.eventTarget.removeEventListener(\n \"turbo:before-prefetch\",\n this.#addKpopLink,\n {\n capture: true,\n passive: true,\n },\n );\n this.eventTarget.removeEventListener(\"focusin\", this.#addKpopLink, {\n capture: true,\n passive: true,\n });\n this.eventTarget.removeEventListener(\"mouseleave\", this.#removeKpopLink, {\n capture: true,\n passive: true,\n });\n this.eventTarget.removeEventListener(\"focusout\", this.#removeKpopLink, {\n capture: true,\n passive: true,\n });\n this.started = false;\n }\n\n #enable = () => {\n if (this.started) return;\n this.started = true;\n this.eventTarget.addEventListener(\"mouseenter\", this.#addKpopLink, {\n capture: true,\n passive: true,\n });\n this.eventTarget.addEventListener(\"focusin\", this.#addKpopLink, {\n capture: true,\n passive: true,\n });\n this.eventTarget.addEventListener(\n \"turbo:before-prefetch\",\n this.#addKpopLink,\n {\n capture: true,\n passive: true,\n },\n );\n this.eventTarget.addEventListener(\"mouseleave\", this.#removeKpopLink, {\n capture: true,\n passive: true,\n });\n this.eventTarget.addEventListener(\"focusout\", this.#removeKpopLink, {\n capture: true,\n passive: true,\n });\n };\n\n #addKpopLink = (event) => {\n const target = event.target;\n const isLink =\n target.matches &&\n target.matches(\n \"a[href]:not([target^=_]):not([download]):not([data-turbo-frame]\",\n );\n if (isLink && this.#isPrefetchable(target)) {\n const link = target;\n const location = getLocationForLink(link);\n if (this.delegate.isModalLink(link, location)) {\n link.dataset.turboFrame = \"kpop\";\n }\n }\n };\n\n #removeKpopLink = (event) => {\n const target = event.target;\n const isLink =\n target.matches && target.matches(\"a[href][data-turbo-frame='kpop']\");\n if (isLink) {\n delete target.dataset.turboFrame;\n }\n };\n\n #isPrefetchable(link) {\n const href = link.getAttribute(\"href\");\n if (!href) return false;\n if (unfetchableLink(link)) return false;\n if (linkToTheSamePage(link)) return false;\n if (linkOptsOut(link)) return false;\n if (nonSafeLink(link)) return false;\n return true;\n }\n}\n\nfunction getLocationForLink(link) {\n return new URL(link.getAttribute(\"href\").toString(), document.baseURI);\n}\n\nconst unfetchableLink = (link) =>\n link.origin !== document.location.origin ||\n ![\"http:\", \"https:\"].includes(link.protocol) ||\n link.hasAttribute(\"target\");\n\nconst linkToTheSamePage = (link) =>\n link.pathname + link.search ===\n document.location.pathname + document.location.search ||\n link.href.startsWith(\"#\");\n\nconst linkOptsOut = (link) => {\n return link.getAttribute(\"data-turbo\") === \"false\";\n};\n\nconst nonSafeLink = (link) => {\n const turboMethod = link.getAttribute(\"data-turbo-method\");\n if (turboMethod && turboMethod.toLowerCase() !== \"get\") return true;\n if (isUJS(link)) return true;\n if (link.hasAttribute(\"data-turbo-confirm\")) return true;\n if (link.hasAttribute(\"data-turbo-stream\")) return true;\n return false;\n};\n\nconst isUJS = (link) =>\n link.hasAttribute(\"data-remote\") ||\n link.hasAttribute(\"data-behavior\") ||\n link.hasAttribute(\"data-confirm\") ||\n link.hasAttribute(\"data-method\");\n","/**\n * Similar to Hotwire's PathConfiguration.json, this class compiles a list of\n * rules to check link hrefs against so that we can identify links that\n * should open in a KPOP modal.\n *\n * Unlike Hotwire Native, we can't intercept 303s in the browser before they\n * load. Browser sandbox prevents us from inspecting the location of redirect\n * requests so we can only intercept links that match modals directly.\n *\n * For posts and redirects, we need server support (flash modals, streams).\n */\nexport default class Ruleset {\n constructor(rules = []) {\n this.rules = [];\n\n rules.forEach((rule) => {\n this.#compileRule(rule);\n });\n }\n\n /**\n * Returns properties for the given URL\n *\n * @param {URL} location\n * @returns {} properties\n */\n properties(location) {\n return this.rules.reduce((c, f) => f(location, c), {});\n }\n\n #compileRule({ patterns, properties }) {\n patterns.forEach((pattern) => {\n this.rules.push(locationMatcher(new RegExp(pattern), properties));\n });\n }\n}\n\nfunction locationMatcher(re, properties) {\n return (location, accumulator) =>\n re.test(location.pathname)\n ? { ...accumulator, ...properties }\n : accumulator;\n}\n","import { Modal } from \"./modal\";\n\nexport class StreamModal extends Modal {\n /**\n * When a turbo-stream[action=kpop_open] element is rendered, it runs this\n * method to load the modal template as a StreamModal.\n *\n * @param {Kpop__FrameController} frame\n * @param {Turbo.StreamElement} action\n */\n static async open(frame, action) {\n const animate = !frame.isOpen;\n\n await frame.dismiss({ animate, reason: \"turbo-stream.kpop_open\" });\n\n frame.element.append(action.templateContent);\n\n const dialog = frame.element.querySelector(\"dialog\");\n const src = dialog.dataset.src;\n\n await frame.open(new StreamModal(frame, dialog, src), { animate });\n }\n}\n","import { Turbo } from \"@hotwired/turbo-rails\";\n\nimport { StreamModal } from \"../modals/stream_modal\";\n\nexport default class StreamActions {\n start() {\n Turbo.StreamActions.kpop_open = openStreamModal;\n }\n\n stop() {\n delete Turbo.StreamActions.kpop_open;\n }\n}\n\nfunction openStreamModal() {\n const frame = this.targetElements[0]?.kpop;\n\n if (frame) {\n StreamModal.open(frame, this).then(() => {});\n }\n}\n","import FrameController from \"../kpop/controllers/frame_controller\";\n\nimport debug from \"./utils/debug\";\nimport LinkObserver from \"./utils/link_observer\";\nimport Ruleset from \"./utils/ruleset\";\nimport StreamActions from \"./utils/stream_actions\";\n\nexport const controllers = [\n { identifier: \"kpop--frame\", controllerConstructor: FrameController },\n];\n\nexport default class Application {\n static configure(config = {}) {\n this.instance ||= new this(config);\n debug.enabled = this.instance.debug;\n return this.instance;\n }\n\n constructor({ rules = [], debug = false } = {}) {\n this.config = { rules, debug };\n this.ruleset = new Ruleset(rules);\n this.linkObserver = new LinkObserver(this, document);\n this.streamActions = new StreamActions();\n }\n\n start() {\n this.streamActions.start();\n this.linkObserver.start();\n\n window.addEventListener(\n \"turbo:before-fetch-request\",\n addKpopToRequestHeaders,\n );\n\n if (this.debug) {\n document.addEventListener(\"focusin\", debugFocusIn);\n document.addEventListener(\"focusout\", debugFocusOut);\n }\n\n return this;\n }\n\n stop() {\n window.removeEventListener(\n \"turbo:before-fetch-request\",\n addKpopToRequestHeaders,\n );\n document.removeEventListener(\"focusin\", debugFocusIn);\n document.removeEventListener(\"focusout\", debugFocusOut);\n\n this.streamActions.stop();\n this.linkObserver.stop();\n }\n\n isModalLink(link, location) {\n const properties = this.ruleset.properties(location);\n return properties.context === \"modal\";\n }\n\n get debug() {\n return Boolean(this.config.debug);\n }\n}\n\nconst debugFocusIn = (e) => debug(\"Application\")(\"focus\", e.target);\nconst debugFocusOut = (e) => debug(\"Application\")(\"blur\", e.target);\n\nconst addKpopToRequestHeaders = (e) => {\n const headers = e.detail.fetchOptions.headers;\n\n if (headers[\"Accept\"]?.includes(\"text/vnd.turbo-stream.html\")) {\n headers[\"Kpop-Available\"] = \"true\";\n }\n};\n"],"names":["enabled","debug","receiver","console","bind","noop","Object","defineProperty","get","set","Modal","constructor","frame","dialog","src","this","element","uri","URL","dataset","window","location","origin","connect","addEventListener","cancel","close","scrim","disconnect","removeEventListener","pathname","search","hash","e","preventDefault","dismiss","animate","reason","clear","target","tagName","open","animation","showModal","removeAttribute","beforeVisit","detail","url","name","el","trigger","duration","defaultValue","value","getComputedStyle","getPropertyValue","num","parseFloat","endsWith","animationDuration","Promise","resolve","resolver","once","clearTimeout","timeout","toggleAttribute","setTimeout","ContentModal","FrameModal","load","visit","hasAttribute","Kpop__FrameController","Controller","static","Boolean","kpop","controller","TurboFrameController","delegate","prototype","_linkClickIntercepted","linkClickIntercepted","id","getAttribute","document","getElementById","Turbo","FrameElement","call","installNavigationInterception","querySelector","then","modal","openValueChanged","isOpen","dismissing","opening","innerHTML","openValue","beforeFrameRender","event","newFrame","baseURI","resume","beforeStreamRender","render","async","stream","toString","frameLoad","firstElementChild","beforeFetchRequest","focusElement","activeElement","body","lastFetchFocusRef","WeakRef","container","previousFocusRef","deref","sourceURL","focus","session","view","forceReloaded","error","isConnected","warn","nextFrame","callback","requestAnimationFrame","LinkObserver","started","eventTarget","start","readyState","enable","stop","addKpopLink","capture","passive","removeKpopLink","matches","isPrefetchable","link","getLocationForLink","isModalLink","turboFrame","unfetchableLink","linkToTheSamePage","linkOptsOut","nonSafeLink","includes","protocol","href","startsWith","turboMethod","toLowerCase","isUJS","Ruleset","rules","forEach","rule","compileRule","properties","reduce","c","f","patterns","pattern","push","re","accumulator","test","locationMatcher","RegExp","StreamModal","action","append","templateContent","StreamActions","kpop_open","openStreamModal","targetElements","controllers","identifier","controllerConstructor","FrameController","Application","configure","config","instance","ruleset","linkObserver","streamActions","addKpopToRequestHeaders","debugFocusIn","debugFocusOut","context","headers","fetchOptions"],"mappings":"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"}
|
|
@@ -96,7 +96,7 @@ export default class Kpop__FrameController extends Controller {
|
|
|
96
96
|
this.debug("event:clear", reason);
|
|
97
97
|
|
|
98
98
|
// clear the src from the frame (if any)
|
|
99
|
-
this.element.src = "";
|
|
99
|
+
if (this.modal?.src === this.element.src) this.element.src = "";
|
|
100
100
|
this.element.innerHTML = "";
|
|
101
101
|
|
|
102
102
|
// mark the modal as hidden
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: katalyst-kpop
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0.
|
|
4
|
+
version: 4.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Katalyst Interactive
|
|
@@ -116,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
117
|
version: '0'
|
|
118
118
|
requirements: []
|
|
119
|
-
rubygems_version:
|
|
119
|
+
rubygems_version: 4.0.3
|
|
120
120
|
specification_version: 4
|
|
121
121
|
summary: Modal library that uses Turbo and Stimulus.
|
|
122
122
|
test_files: []
|