katalyst-kpop 3.0.0.beta.6 → 3.0.0.beta.7

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: ea8b93a5914923b3ba6db7318e0887f3851bfc5774ae6e6790b543900da8d579
4
- data.tar.gz: 336b3aeb96fcd5cc8293365fc2fc45609ec9334167048a93a7ac3d254ea82e36
3
+ metadata.gz: 703872786c0b5e4229301d5b3af0bbf25c114d71cded5d82a000ceaa5b1ce171
4
+ data.tar.gz: a05c973a7e0485e5d01b7e1f9043a4ea18fe72863997310dfe2ab3db1bf17e18
5
5
  SHA512:
6
- metadata.gz: bc928df7baf831a99ca7ef267270cebfae10170c18e91b99863ed830ab330c05807bce81f1a9b82384db4450fb8039c18dfb1cb6929f0c2475e026b6a9a650e7
7
- data.tar.gz: ed9d5a3ab73686931a9494107680b048a5ab316d5e47f4afc315c203d5995505263f26c65a5e6abf62065e50c9d656c83795302d9975dd81c24f3bd91b9e2c83
6
+ metadata.gz: 4afa23866748222ae7d1dd092700dfee01a8885e1afb8c847043f1c117e7f2e72ea1949c325e37c33e4d90b959a019d3ab81a0b282b1ca91da78f58e5f2d4dce
7
+ data.tar.gz: 2f85201edeaf47ac7890a1e3824285ab34e1418d41134d5bd623046c5aabc8ad4ec082c3f27435eb034c8779f8fdc3df5369dc5931b4ef4f21bb2c888f7a3fee
@@ -158,7 +158,7 @@ class Kpop__FrameController extends Controller {
158
158
  this.debug("connect", this.element.src);
159
159
 
160
160
  this.element.kpop = this;
161
- installNavigationInterception(this.element);
161
+ installNavigationInterception(this.element, this.element.delegate);
162
162
 
163
163
  // restoration visit
164
164
  if (this.element.src && this.element.complete) {
@@ -238,11 +238,26 @@ class Kpop__FrameController extends Controller {
238
238
  // the current request (if any) by clearing the src.
239
239
  // Known issue: this won't work if the frame was previously rendering a useful src.
240
240
  if (this.element.hasAttribute("busy")) {
241
+ this.debug("clearing src to cancel turbo request");
241
242
  this.element.src = "";
242
243
  }
243
244
 
245
+ if (this.element.src === location) {
246
+ this.debug("skipping navigate as already on location");
247
+ return false;
248
+ }
249
+
250
+ if (this.element.src !== window.location.href) {
251
+ console.warn("kpop: frame src doesn't match window", this.element.src, window.location.href, location);
252
+ // clear src so that turbo doesn't cache the frame in a loading state
253
+ this.element.delegate.ignoringChangesToAttribute("src", (() => {
254
+ this.element.src = "";
255
+ this.element.delegate.complete = false;
256
+ }));
257
+ }
258
+
244
259
  // Delay turbo's navigateFrame until next tick to let the src change settle.
245
- return Promise.resolve();
260
+ return Promise.resolve(true);
246
261
  }
247
262
 
248
263
  beforeFrameRender(event) {
@@ -354,16 +369,12 @@ class Kpop__FrameController extends Controller {
354
369
  *
355
370
  * @param frameElement turbo-frame element
356
371
  */
357
- function installNavigationInterception(frameElement) {
358
- if (frameElement.delegate._navigateFrame === undefined) {
359
- frameElement.delegate._navigateFrame = frameElement.delegate.navigateFrame;
360
- frameElement.delegate.navigateFrame = async (element, location) => {
361
- await frameElement.kpop?.navigateFrame(element, location);
362
- return frameElement.delegate._navigateFrame.call(
363
- frameElement.delegate,
364
- element,
365
- location
366
- );
372
+ function installNavigationInterception(frameElement, controller) {
373
+ if (controller._navigateFrame === undefined) {
374
+ controller._navigateFrame = controller.navigateFrame;
375
+ controller.navigateFrame = async (element, location) => {
376
+ const navigate = await frameElement.kpop?.navigateFrame(element, location);
377
+ return navigate && controller._navigateFrame(element, location);
367
378
  };
368
379
  }
369
380
  }
@@ -158,7 +158,7 @@ class Kpop__FrameController extends Controller {
158
158
  this.debug("connect", this.element.src);
159
159
 
160
160
  this.element.kpop = this;
161
- installNavigationInterception(this.element);
161
+ installNavigationInterception(this.element, this.element.delegate);
162
162
 
163
163
  // restoration visit
164
164
  if (this.element.src && this.element.complete) {
@@ -238,11 +238,26 @@ class Kpop__FrameController extends Controller {
238
238
  // the current request (if any) by clearing the src.
239
239
  // Known issue: this won't work if the frame was previously rendering a useful src.
240
240
  if (this.element.hasAttribute("busy")) {
241
+ this.debug("clearing src to cancel turbo request");
241
242
  this.element.src = "";
242
243
  }
243
244
 
245
+ if (this.element.src === location) {
246
+ this.debug("skipping navigate as already on location");
247
+ return false;
248
+ }
249
+
250
+ if (this.element.src !== window.location.href) {
251
+ console.warn("kpop: frame src doesn't match window", this.element.src, window.location.href, location);
252
+ // clear src so that turbo doesn't cache the frame in a loading state
253
+ this.element.delegate.ignoringChangesToAttribute("src", (() => {
254
+ this.element.src = "";
255
+ this.element.delegate.complete = false;
256
+ }));
257
+ }
258
+
244
259
  // Delay turbo's navigateFrame until next tick to let the src change settle.
245
- return Promise.resolve();
260
+ return Promise.resolve(true);
246
261
  }
247
262
 
248
263
  beforeFrameRender(event) {
@@ -354,16 +369,12 @@ class Kpop__FrameController extends Controller {
354
369
  *
355
370
  * @param frameElement turbo-frame element
356
371
  */
357
- function installNavigationInterception(frameElement) {
358
- if (frameElement.delegate._navigateFrame === undefined) {
359
- frameElement.delegate._navigateFrame = frameElement.delegate.navigateFrame;
360
- frameElement.delegate.navigateFrame = async (element, location) => {
361
- await frameElement.kpop?.navigateFrame(element, location);
362
- return frameElement.delegate._navigateFrame.call(
363
- frameElement.delegate,
364
- element,
365
- location
366
- );
372
+ function installNavigationInterception(frameElement, controller) {
373
+ if (controller._navigateFrame === undefined) {
374
+ controller._navigateFrame = controller.navigateFrame;
375
+ controller.navigateFrame = async (element, location) => {
376
+ const navigate = await frameElement.kpop?.navigateFrame(element, location);
377
+ return navigate && controller._navigateFrame(element, location);
367
378
  };
368
379
  }
369
380
  }
@@ -1,2 +1,2 @@
1
- import{Controller as e}from"@hotwired/stimulus";import{Turbo as t}from"@hotwired/turbo-rails";class i{constructor(e){this.id=e}async open(){this.debug("open")}async dismiss(){this.debug("dismiss")}beforeVisit(e,t){this.debug("before-visit",t.detail.url)}popstate(e,t){this.debug("popstate",t.state)}async pop(e,t){this.debug("pop");const i=new Promise((t=>{window.addEventListener(e,(()=>{t()}),{once:!0})}));return t(),i}get frameElement(){return document.getElementById(this.id)}get modalElement(){return this.frameElement?.querySelector("[data-controller*='kpop--modal']")}get currentLocationValue(){return this.modalElement?.dataset["kpop-ModalCurrentLocationValue"]||"/"}get fallbackLocationValue(){return this.modalElement?.dataset["kpop-ModalFallbackLocationValue"]||"/"}get isCurrentLocation(){return window.history.state?.turbo&&t.session.location.href===this.src}debug(e,...t){}}class s extends i{constructor(e,t=null){super(e),t&&(this.src=t)}async dismiss(){if(await super.dismiss(),this.visitStarted)this.debug("skipping dismiss, visit started");else{if(this.isCurrentLocation)return this.pop("turbo:load",(()=>{this.debug("turbo-visit",this.fallbackLocationValue),t.visit(this.fallbackLocationValue)}));this.debug("skipping dismiss, not current location")}}beforeVisit(e,t){super.beforeVisit(e,t),this.visitStarted=!0,e.scrimOutlet.hide({animate:!1})}get src(){return new URL(this.currentLocationValue.toString(),document.baseURI).toString()}}class a extends i{constructor(e,t){super(e),this.src=t}async dismiss(){await super.dismiss(),this.isCurrentLocation?await this.pop("turbo:load",(()=>window.history.back())):this.debug("skipping dismiss, not current location")}beforeVisit(e,i){super.beforeVisit(e,i),i.preventDefault(),e.dismiss({animate:!1}).then((()=>{t.visit(i.detail.url),this.debug("before-visit-end")}))}popstate(e,t){super.popstate(e,t),e.scrimOutlet.hide({animate:!1})}}class n extends e{static outlets=["scrim"];static targets=["modal"];static values={open:Boolean};connect(){var e;if(this.debug("connect",this.element.src),this.element.kpop=this,void 0===(e=this.element).delegate._navigateFrame&&(e.delegate._navigateFrame=e.delegate.navigateFrame,e.delegate.navigateFrame=async(t,i)=>(await(e.kpop?.navigateFrame(t,i)),e.delegate._navigateFrame.call(e.delegate,t,i))),this.element.src&&this.element.complete)this.debug("new frame modal",this.element.src),this.open(new a(this.element.id,this.element.src),{animate:!1});else{this.element.querySelector("[data-controller*='kpop--modal']")&&(this.debug("new content modal",window.location.pathname),this.open(new s(this.element.id),{animate:!1}))}}disconnect(){this.debug("disconnect"),delete this.element.kpop,delete this.modal}scrimOutletConnected(e){this.debug("scrim-connected"),this.scrimConnected=!0,this.openValue?e.show({animate:!1}):e.hide({animate:!1})}openValueChanged(e){this.debug("open-changed",e),this.element.parentElement.style.display=e?"flex":"none"}async open(e,{animate:t=!0}={}){return this.isOpen?(this.debug("skip open as already open"),this.modal||=e,!1):this.opening||=this.#e((()=>this.#t(e,{animate:t})))}async dismiss({animate:e=!0,reason:t=""}={}){return this.isOpen?this.dismissing||=this.#e((()=>this.#i({animate:e,reason:t}))):(this.debug("skip dismiss as already closed"),!1)}popstate(e){this.modal?.popstate(this,e)}navigateFrame(e,t){return this.debug("navigate-frame",this.element.src,t),this.element.hasAttribute("busy")&&(this.element.src=""),Promise.resolve()}beforeFrameRender(e){this.debug("before-frame-render",e.detail.newFrame.baseURI),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=e=>{(this.dismissing||Promise.resolve()).then((()=>{this.debug("stream-render",e),t(e)}))}}beforeVisit(e){this.debug("before-visit",e.detail.url),e.detail.url!==this.element.src&&this.isOpen&&this.modal.beforeVisit(this,e)}frameLoad(e){return this.debug("frame-load"),this.open(new a(this.element.id,this.element.src),{animate:!0})}get isOpen(){return this.openValue&&!this.dismissing}async#t(e,{animate:t=!0}={}){this.debug("open-start",{animate:t});const i=this.scrimConnected&&this.scrimOutlet;this.modal=e,this.openValue=!0,await e.open({animate:t}),await(i?.show({animate:t})),delete this.opening,this.debug("open-end")}async#i({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.scrimOutlet.hide({animate:e}),await(this.modal?.dismiss()),this.openValue=!1,this.modal=null,delete this.dismissing,this.debug("dismiss-end")):this.debug("skip dismiss, element detached")}async#e(e){return new Promise(window.requestAnimationFrame).then(e)}debug(e,...t){}}class o extends e{static values={open:Boolean,captive:Boolean,zIndex:Number};connect(){this.defaultZIndexValue=this.zIndexValue,this.defaultCaptiveValue=this.captiveValue,this.element.scrim=this}disconnect(){delete this.element.scrim}async show({captive:e=this.defaultCaptiveValue,zIndex:t=this.defaultZIndexValue,top:i=window.scrollY,animate:s=!0}={}){this.openValue&&await this.hide({animate:s}),this.openValue=!0,this.dispatch("show",{bubbles:!0}),this.#s(e,t,i),s&&(this.element.dataset.showAnimating="",await new Promise((e=>{this.element.addEventListener("animationend",(()=>e()),{once:!0})})),delete this.element.dataset.showAnimating)}async hide({animate:e=!0}={}){this.openValue&&!this.element.dataset.hideAnimating&&(this.dispatch("hide",{bubbles:!0}),e&&(this.element.dataset.hideAnimating="",await new Promise((e=>{this.element.addEventListener("animationend",(()=>e()),{once:!0})})),delete this.element.dataset.hideAnimating),this.#a(),this.openValue=!1)}dismiss(e){this.captiveValue||this.dispatch("dismiss",{bubbles:!0})}escape(e){"Escape"!==e.key||this.captiveValue||e.defaultPrevented||this.dispatch("dismiss",{bubbles:!0})}#s(e,t,i){this.captiveValue=e,this.zIndexValue=t,this.scrollY=i,this.previousPosition=document.body.style.position,this.previousTop=document.body.style.top,this.element.style.zIndex=this.zIndexValue,document.body.style.top=`-${i}px`,document.body.style.position="fixed"}#a(){this.captiveValue=this.defaultCaptiveValue,this.zIndexValue=this.defaultZIndexValue,r(this.element,"z-index",null),r(document.body,"position",null),r(document.body,"top",null),window.scrollTo({left:0,top:this.scrollY,behavior:"instant"}),delete this.scrollY,delete this.previousPosition,delete this.previousTop}}function r(e,t,i){i?e.style.setProperty(t,i):e.style.removeProperty(t)}class d extends i{constructor(e,t){super(e),this.action=t}async open(){await super.open(),window.history.pushState({kpop:!0,id:this.id},"",window.location)}async dismiss(){await super.dismiss(),this.isCurrentLocation&&await this.pop("popstate",(()=>window.history.back())),this.frameElement.innerHTML=""}beforeVisit(e,i){super.beforeVisit(e,i),i.preventDefault(),e.dismiss({animate:!1}).then((()=>{t.visit(i.detail.url),this.debug("before-visit-end")}))}popstate(e,t){super.popstate(e,t),e.dismiss({animate:!0,reason:"popstate"})}get isCurrentLocation(){return window.history.state?.kpop&&window.history.state?.id===this.id}}class l{constructor(e,t){this.frame=e,this.action=t}render(){this.frame.src="",this.frame.innerHTML="",this.frame.append(this.action.templateContent)}}function h(e){return e.targetElements[0]?.kpop}t.StreamActions.kpop_open=function(){const e=!h(this).openValue;h(this)?.dismiss({animate:e,reason:"before-turbo-stream"}).then((()=>{new l(this.targetElements[0],this).render(),h(this)?.open(new d(this.target,this),{animate:e})}))},t.StreamActions.kpop_dismiss=function(){h(this)?.dismiss({reason:"turbo_stream.kpop.dismiss"})},t.StreamActions.kpop_redirect_to=function(){if(this.dataset.turboFrame===this.target){const e=document.createElement("A");e.setAttribute("data-turbo-action","replace"),this.targetElements[0].delegate.navigateFrame(e,this.getAttribute("href"))}else t.visit(this.getAttribute("href"),{action:this.dataset.turboAction})};const m=[{identifier:"kpop--frame",controllerConstructor:n},{identifier:"kpop--modal",controllerConstructor:class extends e{static values={fallback_location:String,layout:String};connect(){this.debug("connect"),this.layoutValue&&document.querySelector("#kpop").classList.toggle(this.layoutValue,!0)}disconnect(){this.debug("disconnect"),this.layoutValue&&document.querySelector("#kpop").classList.toggle(this.layoutValue,!1)}debug(e,...t){}}},{identifier:"scrim",controllerConstructor:o}];export{m as default};
1
+ import{Controller as e}from"@hotwired/stimulus";import{Turbo as t}from"@hotwired/turbo-rails";class i{constructor(e){this.id=e}async open(){this.debug("open")}async dismiss(){this.debug("dismiss")}beforeVisit(e,t){this.debug("before-visit",t.detail.url)}popstate(e,t){this.debug("popstate",t.state)}async pop(e,t){this.debug("pop");const i=new Promise((t=>{window.addEventListener(e,(()=>{t()}),{once:!0})}));return t(),i}get frameElement(){return document.getElementById(this.id)}get modalElement(){return this.frameElement?.querySelector("[data-controller*='kpop--modal']")}get currentLocationValue(){return this.modalElement?.dataset["kpop-ModalCurrentLocationValue"]||"/"}get fallbackLocationValue(){return this.modalElement?.dataset["kpop-ModalFallbackLocationValue"]||"/"}get isCurrentLocation(){return window.history.state?.turbo&&t.session.location.href===this.src}debug(e,...t){}}class s extends i{constructor(e,t=null){super(e),t&&(this.src=t)}async dismiss(){if(await super.dismiss(),this.visitStarted)this.debug("skipping dismiss, visit started");else{if(this.isCurrentLocation)return this.pop("turbo:load",(()=>{this.debug("turbo-visit",this.fallbackLocationValue),t.visit(this.fallbackLocationValue)}));this.debug("skipping dismiss, not current location")}}beforeVisit(e,t){super.beforeVisit(e,t),this.visitStarted=!0,e.scrimOutlet.hide({animate:!1})}get src(){return new URL(this.currentLocationValue.toString(),document.baseURI).toString()}}class n extends i{constructor(e,t){super(e),this.src=t}async dismiss(){await super.dismiss(),this.isCurrentLocation?await this.pop("turbo:load",(()=>window.history.back())):this.debug("skipping dismiss, not current location")}beforeVisit(e,i){super.beforeVisit(e,i),i.preventDefault(),e.dismiss({animate:!1}).then((()=>{t.visit(i.detail.url),this.debug("before-visit-end")}))}popstate(e,t){super.popstate(e,t),e.scrimOutlet.hide({animate:!1})}}class a extends e{static outlets=["scrim"];static targets=["modal"];static values={open:Boolean};connect(){var e,t;if(this.debug("connect",this.element.src),this.element.kpop=this,e=this.element,void 0===(t=this.element.delegate)._navigateFrame&&(t._navigateFrame=t.navigateFrame,t.navigateFrame=async(i,s)=>await(e.kpop?.navigateFrame(i,s))&&t._navigateFrame(i,s)),this.element.src&&this.element.complete)this.debug("new frame modal",this.element.src),this.open(new n(this.element.id,this.element.src),{animate:!1});else{this.element.querySelector("[data-controller*='kpop--modal']")&&(this.debug("new content modal",window.location.pathname),this.open(new s(this.element.id),{animate:!1}))}}disconnect(){this.debug("disconnect"),delete this.element.kpop,delete this.modal}scrimOutletConnected(e){this.debug("scrim-connected"),this.scrimConnected=!0,this.openValue?e.show({animate:!1}):e.hide({animate:!1})}openValueChanged(e){this.debug("open-changed",e),this.element.parentElement.style.display=e?"flex":"none"}async open(e,{animate:t=!0}={}){return this.isOpen?(this.debug("skip open as already open"),this.modal||=e,!1):this.opening||=this.#e((()=>this.#t(e,{animate:t})))}async dismiss({animate:e=!0,reason:t=""}={}){return this.isOpen?this.dismissing||=this.#e((()=>this.#i({animate:e,reason:t}))):(this.debug("skip dismiss as already closed"),!1)}popstate(e){this.modal?.popstate(this,e)}navigateFrame(e,t){return this.debug("navigate-frame",this.element.src,t),this.element.hasAttribute("busy")&&(this.debug("clearing src to cancel turbo request"),this.element.src=""),this.element.src===t?(this.debug("skipping navigate as already on location"),!1):(this.element.src!==window.location.href&&(console.warn("kpop: frame src doesn't match window",this.element.src,window.location.href,t),this.element.delegate.ignoringChangesToAttribute("src",(()=>{this.element.src="",this.element.delegate.complete=!1}))),Promise.resolve(!0))}beforeFrameRender(e){this.debug("before-frame-render",e.detail.newFrame.baseURI),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=e=>{(this.dismissing||Promise.resolve()).then((()=>{this.debug("stream-render",e),t(e)}))}}beforeVisit(e){this.debug("before-visit",e.detail.url),e.detail.url!==this.element.src&&this.isOpen&&this.modal.beforeVisit(this,e)}frameLoad(e){return this.debug("frame-load"),this.open(new n(this.element.id,this.element.src),{animate:!0})}get isOpen(){return this.openValue&&!this.dismissing}async#t(e,{animate:t=!0}={}){this.debug("open-start",{animate:t});const i=this.scrimConnected&&this.scrimOutlet;this.modal=e,this.openValue=!0,await e.open({animate:t}),await(i?.show({animate:t})),delete this.opening,this.debug("open-end")}async#i({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.scrimOutlet.hide({animate:e}),await(this.modal?.dismiss()),this.openValue=!1,this.modal=null,delete this.dismissing,this.debug("dismiss-end")):this.debug("skip dismiss, element detached")}async#e(e){return new Promise(window.requestAnimationFrame).then(e)}debug(e,...t){}}class o extends e{static values={open:Boolean,captive:Boolean,zIndex:Number};connect(){this.defaultZIndexValue=this.zIndexValue,this.defaultCaptiveValue=this.captiveValue,this.element.scrim=this}disconnect(){delete this.element.scrim}async show({captive:e=this.defaultCaptiveValue,zIndex:t=this.defaultZIndexValue,top:i=window.scrollY,animate:s=!0}={}){this.openValue&&await this.hide({animate:s}),this.openValue=!0,this.dispatch("show",{bubbles:!0}),this.#s(e,t,i),s&&(this.element.dataset.showAnimating="",await new Promise((e=>{this.element.addEventListener("animationend",(()=>e()),{once:!0})})),delete this.element.dataset.showAnimating)}async hide({animate:e=!0}={}){this.openValue&&!this.element.dataset.hideAnimating&&(this.dispatch("hide",{bubbles:!0}),e&&(this.element.dataset.hideAnimating="",await new Promise((e=>{this.element.addEventListener("animationend",(()=>e()),{once:!0})})),delete this.element.dataset.hideAnimating),this.#n(),this.openValue=!1)}dismiss(e){this.captiveValue||this.dispatch("dismiss",{bubbles:!0})}escape(e){"Escape"!==e.key||this.captiveValue||e.defaultPrevented||this.dispatch("dismiss",{bubbles:!0})}#s(e,t,i){this.captiveValue=e,this.zIndexValue=t,this.scrollY=i,this.previousPosition=document.body.style.position,this.previousTop=document.body.style.top,this.element.style.zIndex=this.zIndexValue,document.body.style.top=`-${i}px`,document.body.style.position="fixed"}#n(){this.captiveValue=this.defaultCaptiveValue,this.zIndexValue=this.defaultZIndexValue,r(this.element,"z-index",null),r(document.body,"position",null),r(document.body,"top",null),window.scrollTo({left:0,top:this.scrollY,behavior:"instant"}),delete this.scrollY,delete this.previousPosition,delete this.previousTop}}function r(e,t,i){i?e.style.setProperty(t,i):e.style.removeProperty(t)}class d extends i{constructor(e,t){super(e),this.action=t}async open(){await super.open(),window.history.pushState({kpop:!0,id:this.id},"",window.location)}async dismiss(){await super.dismiss(),this.isCurrentLocation&&await this.pop("popstate",(()=>window.history.back())),this.frameElement.innerHTML=""}beforeVisit(e,i){super.beforeVisit(e,i),i.preventDefault(),e.dismiss({animate:!1}).then((()=>{t.visit(i.detail.url),this.debug("before-visit-end")}))}popstate(e,t){super.popstate(e,t),e.dismiss({animate:!0,reason:"popstate"})}get isCurrentLocation(){return window.history.state?.kpop&&window.history.state?.id===this.id}}class l{constructor(e,t){this.frame=e,this.action=t}render(){this.frame.src="",this.frame.innerHTML="",this.frame.append(this.action.templateContent)}}function h(e){return e.targetElements[0]?.kpop}t.StreamActions.kpop_open=function(){const e=!h(this).openValue;h(this)?.dismiss({animate:e,reason:"before-turbo-stream"}).then((()=>{new l(this.targetElements[0],this).render(),h(this)?.open(new d(this.target,this),{animate:e})}))},t.StreamActions.kpop_dismiss=function(){h(this)?.dismiss({reason:"turbo_stream.kpop.dismiss"})},t.StreamActions.kpop_redirect_to=function(){if(this.dataset.turboFrame===this.target){const e=document.createElement("A");e.setAttribute("data-turbo-action","replace"),this.targetElements[0].delegate.navigateFrame(e,this.getAttribute("href"))}else t.visit(this.getAttribute("href"),{action:this.dataset.turboAction})};const m=[{identifier:"kpop--frame",controllerConstructor:a},{identifier:"kpop--modal",controllerConstructor:class extends e{static values={fallback_location:String,layout:String};connect(){this.debug("connect"),this.layoutValue&&document.querySelector("#kpop").classList.toggle(this.layoutValue,!0)}disconnect(){this.debug("disconnect"),this.layoutValue&&document.querySelector("#kpop").classList.toggle(this.layoutValue,!1)}debug(e,...t){}}},{identifier:"scrim",controllerConstructor:o}];export{m as default};
2
2
  //# sourceMappingURL=kpop.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"kpop.min.js","sources":["../../../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/controllers/scrim_controller.js","../../../javascript/kpop/modals/stream_modal.js","../../../javascript/kpop/utils/stream_renderer.js","../../../javascript/kpop/turbo_actions.js","../../../javascript/kpop/application.js","../../../javascript/kpop/controllers/modal_controller.js"],"sourcesContent":["import { Turbo } from \"@hotwired/turbo-rails\";\n\nimport DEBUG from \"../debug\";\n\nexport class Modal {\n constructor(id) {\n this.id = id;\n }\n\n async open() {\n this.debug(\"open\");\n }\n\n async dismiss() {\n this.debug(`dismiss`);\n }\n\n beforeVisit(frame, e) {\n this.debug(`before-visit`, e.detail.url);\n }\n\n popstate(frame, e) {\n this.debug(`popstate`, e.state);\n }\n\n async pop(event, callback) {\n this.debug(`pop`);\n\n const promise = new Promise((resolve) => {\n window.addEventListener(\n event,\n () => {\n resolve();\n },\n { once: true }\n );\n });\n\n callback();\n\n return promise;\n }\n\n get frameElement() {\n return document.getElementById(this.id);\n }\n\n get modalElement() {\n return this.frameElement?.querySelector(\"[data-controller*='kpop--modal']\");\n }\n\n get currentLocationValue() {\n return this.modalElement?.dataset[\"kpop-ModalCurrentLocationValue\"] || \"/\";\n }\n\n get fallbackLocationValue() {\n return this.modalElement?.dataset[\"kpop-ModalFallbackLocationValue\"] || \"/\";\n }\n\n get isCurrentLocation() {\n return (\n window.history.state?.turbo && Turbo.session.location.href === this.src\n );\n }\n\n debug(event, ...args) {\n if (DEBUG) console.debug(`${this.constructor.name}:${event}`, ...args);\n }\n}\n","import { Turbo } from \"@hotwired/turbo-rails\";\n\nimport { Modal } from \"./modal\";\n\nexport class ContentModal extends Modal {\n constructor(id, src = null) {\n super(id);\n\n if (src) this.src = src;\n }\n\n async dismiss() {\n await super.dismiss();\n\n if (this.visitStarted) {\n this.debug(\"skipping dismiss, visit started\");\n return;\n }\n if (!this.isCurrentLocation) {\n this.debug(\"skipping dismiss, not current location\");\n return;\n }\n\n return this.pop(\"turbo:load\", () => {\n this.debug(\"turbo-visit\", this.fallbackLocationValue);\n Turbo.visit(this.fallbackLocationValue);\n });\n\n // no specific close action required, this is turbo's responsibility\n }\n\n beforeVisit(frame, e) {\n super.beforeVisit(frame, e);\n\n this.visitStarted = true;\n\n frame.scrimOutlet.hide({ animate: false });\n }\n\n get src() {\n return new URL(\n this.currentLocationValue.toString(),\n document.baseURI\n ).toString();\n }\n}\n","import { Turbo } from \"@hotwired/turbo-rails\";\n\nimport { Modal } from \"./modal\";\n\nexport class FrameModal extends Modal {\n constructor(id, src) {\n super(id);\n this.src = src;\n }\n\n async dismiss() {\n await super.dismiss();\n\n if (!this.isCurrentLocation) {\n this.debug(\"skipping dismiss, not current location\");\n } else {\n await this.pop(\"turbo:load\", () => window.history.back());\n }\n\n // no specific close action required, this is turbo's responsibility\n }\n\n beforeVisit(frame, e) {\n super.beforeVisit(frame, e);\n\n e.preventDefault();\n\n frame.dismiss({ animate: false }).then(() => {\n Turbo.visit(e.detail.url);\n\n this.debug(\"before-visit-end\");\n });\n }\n\n popstate(frame, e) {\n super.popstate(frame, e);\n\n // Turbo will restore modal state, but we need to reset the scrim\n frame.scrimOutlet.hide({ animate: false });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nimport DEBUG from \"../debug\";\nimport { ContentModal } from \"../modals/content_modal\";\nimport { FrameModal } from \"../modals/frame_modal\";\n\nexport default class Kpop__FrameController extends Controller {\n static outlets = [\"scrim\"];\n static targets = [\"modal\"];\n static values = {\n open: Boolean,\n };\n\n connect() {\n this.debug(\"connect\", this.element.src);\n\n this.element.kpop = this;\n installNavigationInterception(this.element);\n\n // restoration visit\n if (this.element.src && this.element.complete) {\n this.debug(\"new frame modal\", this.element.src);\n this.open(new FrameModal(this.element.id, this.element.src), {\n animate: false,\n });\n } else {\n const element = this.element.querySelector(\n \"[data-controller*='kpop--modal']\"\n );\n if (element) {\n this.debug(\"new content modal\", window.location.pathname);\n this.open(new ContentModal(this.element.id), { animate: false });\n }\n }\n }\n\n disconnect() {\n this.debug(\"disconnect\");\n\n delete this.element.kpop;\n delete this.modal;\n }\n\n scrimOutletConnected(scrim) {\n this.debug(\"scrim-connected\");\n\n this.scrimConnected = true;\n\n if (this.openValue) {\n scrim.show({ animate: false });\n } else {\n scrim.hide({ animate: false });\n }\n }\n\n openValueChanged(open) {\n this.debug(\"open-changed\", open);\n\n this.element.parentElement.style.display = open ? \"flex\" : \"none\";\n }\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 return (this.opening ||= this.#nextFrame(() =>\n this.#open(modal, { animate })\n ));\n }\n\n async dismiss({ animate = true, reason = \"\" } = {}) {\n if (!this.isOpen) {\n this.debug(\"skip dismiss as already closed\");\n return false;\n }\n\n return (this.dismissing ||= this.#nextFrame(() =>\n this.#dismiss({ animate, reason })\n ));\n }\n\n // EVENTS\n\n popstate(event) {\n this.modal?.popstate(this, event);\n }\n\n navigateFrame(element, location) {\n this.debug(\"navigate-frame\", this.element.src, location);\n\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 (this.element.hasAttribute(\"busy\")) {\n this.element.src = \"\";\n }\n\n // Delay turbo's navigateFrame until next tick to let the src change settle.\n return Promise.resolve();\n }\n\n beforeFrameRender(event) {\n this.debug(\"before-frame-render\", event.detail.newFrame.baseURI);\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 = (stream) => {\n (this.dismissing || Promise.resolve()).then(() => {\n this.debug(\"stream-render\", stream);\n resume(stream);\n });\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 // ignore unless we're open\n if (!this.isOpen) return;\n\n this.modal.beforeVisit(this, e);\n }\n\n frameLoad(event) {\n this.debug(\"frame-load\");\n\n return this.open(new FrameModal(this.element.id, this.element.src), {\n animate: true,\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 const scrim = this.scrimConnected && this.scrimOutlet;\n\n this.modal = modal;\n this.openValue = true;\n\n await modal.open({ animate });\n await scrim?.show({ animate });\n\n delete this.opening;\n\n this.debug(\"open-end\");\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 if (DEBUG) debugger;\n }\n\n await this.scrimOutlet.hide({ animate });\n await this.modal?.dismiss();\n\n this.openValue = false;\n this.modal = null;\n delete this.dismissing;\n\n this.debug(\"dismiss-end\");\n }\n\n async #nextFrame(callback) {\n return new Promise(window.requestAnimationFrame).then(callback);\n }\n\n debug(event, ...args) {\n if (DEBUG) console.debug(`FrameController:${event}`, ...args);\n }\n}\n\n/**\n * Monkey patch for Turbo#FrameController.\n *\n * Intercept calls to navigateFrame(element, location) and ensures that src is\n * cleared if the frame is busy so that we don't restore an in-progress src on\n * restoration visits.\n *\n * See Turbo issue: https://github.com/hotwired/turbo/issues/1055\n *\n * @param frameElement turbo-frame element\n */\nfunction installNavigationInterception(frameElement) {\n if (frameElement.delegate._navigateFrame === undefined) {\n frameElement.delegate._navigateFrame = frameElement.delegate.navigateFrame;\n frameElement.delegate.navigateFrame = async (element, location) => {\n await frameElement.kpop?.navigateFrame(element, location);\n return frameElement.delegate._navigateFrame.call(\n frameElement.delegate,\n element,\n location\n );\n };\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nimport DEBUG from \"../debug\";\n\n/**\n * Scrim controller wraps an element that creates a whole page layer.\n * It is intended to be used behind a modal or nav drawer.\n *\n * If the Scrim element receives a click event, it automatically triggers \"scrim:hide\".\n *\n * You can show and hide the scrim programmatically by calling show/hide on the controller, e.g. using an outlet.\n *\n * If you need to respond to the scrim showing or hiding you should subscribe to \"scrim:show\" and \"scrim:hide\".\n */\nexport default class ScrimController extends Controller {\n static values = {\n open: Boolean,\n captive: Boolean,\n zIndex: Number,\n };\n\n connect() {\n if (DEBUG) console.debug(\"scrim:connect\");\n\n this.defaultZIndexValue = this.zIndexValue;\n this.defaultCaptiveValue = this.captiveValue;\n\n this.element.scrim = this;\n }\n\n disconnect() {\n if (DEBUG) console.debug(\"scrim:disconnect\");\n\n delete this.element.scrim;\n }\n\n async show({\n captive = this.defaultCaptiveValue,\n zIndex = this.defaultZIndexValue,\n top = window.scrollY,\n animate = true,\n } = {}) {\n if (DEBUG) console.debug(\"scrim:before-show\");\n\n // hide the scrim before opening the new one if it's already open\n if (this.openValue) {\n await this.hide({ animate });\n }\n\n // update internal state\n this.openValue = true;\n\n // notify listeners of pending request\n this.dispatch(\"show\", { bubbles: true });\n\n if (DEBUG) console.debug(\"scrim:show-start\");\n\n // update state, perform style updates\n this.#show(captive, zIndex, top);\n\n if (animate) {\n // animate opening\n // this will trigger an animationEnd event via CSS that completes the open\n this.element.dataset.showAnimating = \"\";\n\n await new Promise((resolve) => {\n this.element.addEventListener(\"animationend\", () => resolve(), {\n once: true,\n });\n });\n\n delete this.element.dataset.showAnimating;\n }\n\n if (DEBUG) console.debug(\"scrim:show-end\");\n }\n\n async hide({ animate = true } = {}) {\n if (!this.openValue || this.element.dataset.hideAnimating) return;\n\n if (DEBUG) console.debug(\"scrim:before-hide\");\n\n // notify listeners of pending request\n this.dispatch(\"hide\", { bubbles: true });\n\n if (DEBUG) console.debug(\"scrim:hide-start\");\n\n if (animate) {\n // set animation state\n // this will trigger an animationEnd event via CSS that completes the hide\n this.element.dataset.hideAnimating = \"\";\n\n await new Promise((resolve) => {\n this.element.addEventListener(\"animationend\", () => resolve(), {\n once: true,\n });\n });\n\n delete this.element.dataset.hideAnimating;\n }\n\n this.#hide();\n\n this.openValue = false;\n\n if (DEBUG) console.debug(\"scrim:hide-end\");\n }\n\n dismiss(event) {\n if (DEBUG) console.debug(\"scrim:dismiss\");\n\n if (!this.captiveValue) this.dispatch(\"dismiss\", { bubbles: true });\n }\n\n escape(event) {\n if (\n event.key === \"Escape\" &&\n !this.captiveValue &&\n !event.defaultPrevented\n ) {\n this.dispatch(\"dismiss\", { bubbles: true });\n }\n }\n\n /**\n * Clips body to viewport size and sets the z-index\n */\n #show(captive, zIndex, top) {\n this.captiveValue = captive;\n this.zIndexValue = zIndex;\n this.scrollY = top;\n\n this.previousPosition = document.body.style.position;\n this.previousTop = document.body.style.top;\n\n this.element.style.zIndex = this.zIndexValue;\n document.body.style.top = `-${top}px`;\n document.body.style.position = \"fixed\";\n }\n\n /**\n * Unclips body from viewport size and unsets the z-index\n */\n #hide() {\n this.captiveValue = this.defaultCaptiveValue;\n this.zIndexValue = this.defaultZIndexValue;\n\n resetStyle(this.element, \"z-index\", null);\n resetStyle(document.body, \"position\", null);\n resetStyle(document.body, \"top\", null);\n\n window.scrollTo({ left: 0, top: this.scrollY, behavior: \"instant\" });\n\n delete this.scrollY;\n delete this.previousPosition;\n delete this.previousTop;\n }\n}\n\nfunction resetStyle(element, property, previousValue) {\n if (previousValue) {\n element.style.setProperty(property, previousValue);\n } else {\n element.style.removeProperty(property);\n }\n}\n","import { Turbo } from \"@hotwired/turbo-rails\";\n\nimport { Modal } from \"./modal\";\n\nexport class StreamModal extends Modal {\n constructor(id, action) {\n super(id);\n\n this.action = action;\n }\n\n async open() {\n await super.open();\n\n window.history.pushState({ kpop: true, id: this.id }, \"\", window.location);\n }\n\n async dismiss() {\n await super.dismiss();\n\n if (this.isCurrentLocation) {\n await this.pop(\"popstate\", () => window.history.back());\n }\n\n this.frameElement.innerHTML = \"\";\n }\n\n beforeVisit(frame, e) {\n super.beforeVisit(frame, e);\n\n e.preventDefault();\n\n frame.dismiss({ animate: false }).then(() => {\n Turbo.visit(e.detail.url);\n\n this.debug(\"before-visit-end\");\n });\n }\n\n popstate(frame, e) {\n super.popstate(frame, e);\n\n frame.dismiss({ animate: true, reason: \"popstate\" });\n }\n\n get isCurrentLocation() {\n return window.history.state?.kpop && window.history.state?.id === this.id;\n }\n}\n","import DEBUG from \"../debug\";\n\nexport class StreamRenderer {\n constructor(frame, action) {\n this.frame = frame;\n this.action = action;\n }\n\n render() {\n if (DEBUG) console.debug(\"stream-renderer:render\");\n this.frame.src = \"\";\n this.frame.innerHTML = \"\";\n this.frame.append(this.action.templateContent);\n }\n}\n","import { Turbo } from \"@hotwired/turbo-rails\";\n\nimport DEBUG from \"./debug\";\n\nimport { StreamModal } from \"./modals/stream_modal\";\nimport { StreamRenderer } from \"./utils/stream_renderer\";\n\nfunction kpop(action) {\n return action.targetElements[0]?.kpop;\n}\n\nTurbo.StreamActions.kpop_open = function () {\n const animate = !kpop(this).openValue;\n\n kpop(this)\n ?.dismiss({ animate, reason: \"before-turbo-stream\" })\n .then(() => {\n new StreamRenderer(this.targetElements[0], this).render();\n kpop(this)?.open(new StreamModal(this.target, this), { animate });\n });\n};\n\nTurbo.StreamActions.kpop_dismiss = function () {\n kpop(this)?.dismiss({ reason: \"turbo_stream.kpop.dismiss\" });\n};\n\nTurbo.StreamActions.kpop_redirect_to = function () {\n if (this.dataset.turboFrame === this.target) {\n if (DEBUG)\n console.debug(\n `kpop: redirecting ${this.target} to ${this.getAttribute(\"href\")}`\n );\n const a = document.createElement(\"A\");\n a.setAttribute(\"data-turbo-action\", \"replace\");\n this.targetElements[0].delegate.navigateFrame(a, this.getAttribute(\"href\"));\n } else {\n if (DEBUG)\n console.debug(`kpop: redirecting to ${this.getAttribute(\"href\")}`);\n Turbo.visit(this.getAttribute(\"href\"), {\n action: this.dataset.turboAction,\n });\n }\n};\n","import FrameController from \"../kpop/controllers/frame_controller\";\nimport ModalController from \"../kpop/controllers/modal_controller\";\nimport ScrimController from \"../kpop/controllers/scrim_controller\";\n\nimport \"./turbo_actions\";\n\nconst Definitions = [\n { identifier: \"kpop--frame\", controllerConstructor: FrameController },\n { identifier: \"kpop--modal\", controllerConstructor: ModalController },\n { identifier: \"scrim\", controllerConstructor: ScrimController },\n];\n\nexport { Definitions as default };\n","import { Controller } from \"@hotwired/stimulus\";\n\nimport DEBUG from \"../debug\";\n\nexport default class Kpop__ModalController extends Controller {\n static values = {\n fallback_location: String,\n layout: String,\n };\n\n connect() {\n this.debug(\"connect\");\n\n if (this.layoutValue) {\n document.querySelector(\"#kpop\").classList.toggle(this.layoutValue, true);\n }\n }\n\n disconnect() {\n this.debug(\"disconnect\");\n\n if (this.layoutValue) {\n document.querySelector(\"#kpop\").classList.toggle(this.layoutValue, false);\n }\n }\n\n debug(event, ...args) {\n if (DEBUG) console.debug(`ModalController:${event}`, ...args);\n }\n}\n"],"names":["Modal","constructor","id","this","open","debug","dismiss","beforeVisit","frame","e","detail","url","popstate","state","pop","event","callback","promise","Promise","resolve","window","addEventListener","once","frameElement","document","getElementById","modalElement","querySelector","currentLocationValue","dataset","fallbackLocationValue","isCurrentLocation","history","turbo","Turbo","session","location","href","src","args","ContentModal","super","visitStarted","visit","scrimOutlet","hide","animate","URL","toString","baseURI","FrameModal","back","preventDefault","then","Kpop__FrameController","Controller","static","Boolean","connect","element","kpop","undefined","delegate","_navigateFrame","navigateFrame","async","call","complete","pathname","disconnect","modal","scrimOutletConnected","scrim","scrimConnected","openValue","show","openValueChanged","parentElement","style","display","isOpen","opening","nextFrame","reason","dismissing","hasAttribute","beforeFrameRender","newFrame","resume","beforeStreamRender","render","stream","frameLoad","isConnected","console","warn","requestAnimationFrame","ScrimController","captive","zIndex","Number","defaultZIndexValue","zIndexValue","defaultCaptiveValue","captiveValue","top","scrollY","dispatch","bubbles","showAnimating","hideAnimating","escape","key","defaultPrevented","previousPosition","body","position","previousTop","resetStyle","scrollTo","left","behavior","property","previousValue","setProperty","removeProperty","StreamModal","action","pushState","innerHTML","StreamRenderer","append","templateContent","targetElements","StreamActions","kpop_open","target","kpop_dismiss","kpop_redirect_to","turboFrame","a","createElement","setAttribute","getAttribute","turboAction","Definitions","identifier","controllerConstructor","FrameController","fallback_location","String","layout","layoutValue","classList","toggle"],"mappings":"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"}
1
+ {"version":3,"file":"kpop.min.js","sources":["../../../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/controllers/scrim_controller.js","../../../javascript/kpop/modals/stream_modal.js","../../../javascript/kpop/utils/stream_renderer.js","../../../javascript/kpop/turbo_actions.js","../../../javascript/kpop/application.js","../../../javascript/kpop/controllers/modal_controller.js"],"sourcesContent":["import { Turbo } from \"@hotwired/turbo-rails\";\n\nimport DEBUG from \"../debug\";\n\nexport class Modal {\n constructor(id) {\n this.id = id;\n }\n\n async open() {\n this.debug(\"open\");\n }\n\n async dismiss() {\n this.debug(`dismiss`);\n }\n\n beforeVisit(frame, e) {\n this.debug(`before-visit`, e.detail.url);\n }\n\n popstate(frame, e) {\n this.debug(`popstate`, e.state);\n }\n\n async pop(event, callback) {\n this.debug(`pop`);\n\n const promise = new Promise((resolve) => {\n window.addEventListener(\n event,\n () => {\n resolve();\n },\n { once: true }\n );\n });\n\n callback();\n\n return promise;\n }\n\n get frameElement() {\n return document.getElementById(this.id);\n }\n\n get modalElement() {\n return this.frameElement?.querySelector(\"[data-controller*='kpop--modal']\");\n }\n\n get currentLocationValue() {\n return this.modalElement?.dataset[\"kpop-ModalCurrentLocationValue\"] || \"/\";\n }\n\n get fallbackLocationValue() {\n return this.modalElement?.dataset[\"kpop-ModalFallbackLocationValue\"] || \"/\";\n }\n\n get isCurrentLocation() {\n return (\n window.history.state?.turbo && Turbo.session.location.href === this.src\n );\n }\n\n debug(event, ...args) {\n if (DEBUG) console.debug(`${this.constructor.name}:${event}`, ...args);\n }\n}\n","import { Turbo } from \"@hotwired/turbo-rails\";\n\nimport { Modal } from \"./modal\";\n\nexport class ContentModal extends Modal {\n constructor(id, src = null) {\n super(id);\n\n if (src) this.src = src;\n }\n\n async dismiss() {\n await super.dismiss();\n\n if (this.visitStarted) {\n this.debug(\"skipping dismiss, visit started\");\n return;\n }\n if (!this.isCurrentLocation) {\n this.debug(\"skipping dismiss, not current location\");\n return;\n }\n\n return this.pop(\"turbo:load\", () => {\n this.debug(\"turbo-visit\", this.fallbackLocationValue);\n Turbo.visit(this.fallbackLocationValue);\n });\n\n // no specific close action required, this is turbo's responsibility\n }\n\n beforeVisit(frame, e) {\n super.beforeVisit(frame, e);\n\n this.visitStarted = true;\n\n frame.scrimOutlet.hide({ animate: false });\n }\n\n get src() {\n return new URL(\n this.currentLocationValue.toString(),\n document.baseURI\n ).toString();\n }\n}\n","import { Turbo } from \"@hotwired/turbo-rails\";\n\nimport { Modal } from \"./modal\";\n\nexport class FrameModal extends Modal {\n constructor(id, src) {\n super(id);\n this.src = src;\n }\n\n async dismiss() {\n await super.dismiss();\n\n if (!this.isCurrentLocation) {\n this.debug(\"skipping dismiss, not current location\");\n } else {\n await this.pop(\"turbo:load\", () => window.history.back());\n }\n\n // no specific close action required, this is turbo's responsibility\n }\n\n beforeVisit(frame, e) {\n super.beforeVisit(frame, e);\n\n e.preventDefault();\n\n frame.dismiss({ animate: false }).then(() => {\n Turbo.visit(e.detail.url);\n\n this.debug(\"before-visit-end\");\n });\n }\n\n popstate(frame, e) {\n super.popstate(frame, e);\n\n // Turbo will restore modal state, but we need to reset the scrim\n frame.scrimOutlet.hide({ animate: false });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nimport DEBUG from \"../debug\";\nimport { ContentModal } from \"../modals/content_modal\";\nimport { FrameModal } from \"../modals/frame_modal\";\n\nexport default class Kpop__FrameController extends Controller {\n static outlets = [\"scrim\"];\n static targets = [\"modal\"];\n static values = {\n open: Boolean,\n };\n\n connect() {\n this.debug(\"connect\", this.element.src);\n\n this.element.kpop = this;\n installNavigationInterception(this.element, this.element.delegate);\n\n // restoration visit\n if (this.element.src && this.element.complete) {\n this.debug(\"new frame modal\", this.element.src);\n this.open(new FrameModal(this.element.id, this.element.src), {\n animate: false,\n });\n } else {\n const element = this.element.querySelector(\n \"[data-controller*='kpop--modal']\"\n );\n if (element) {\n this.debug(\"new content modal\", window.location.pathname);\n this.open(new ContentModal(this.element.id), { animate: false });\n }\n }\n }\n\n disconnect() {\n this.debug(\"disconnect\");\n\n delete this.element.kpop;\n delete this.modal;\n }\n\n scrimOutletConnected(scrim) {\n this.debug(\"scrim-connected\");\n\n this.scrimConnected = true;\n\n if (this.openValue) {\n scrim.show({ animate: false });\n } else {\n scrim.hide({ animate: false });\n }\n }\n\n openValueChanged(open) {\n this.debug(\"open-changed\", open);\n\n this.element.parentElement.style.display = open ? \"flex\" : \"none\";\n }\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 return (this.opening ||= this.#nextFrame(() =>\n this.#open(modal, { animate })\n ));\n }\n\n async dismiss({ animate = true, reason = \"\" } = {}) {\n if (!this.isOpen) {\n this.debug(\"skip dismiss as already closed\");\n return false;\n }\n\n return (this.dismissing ||= this.#nextFrame(() =>\n this.#dismiss({ animate, reason })\n ));\n }\n\n // EVENTS\n\n popstate(event) {\n this.modal?.popstate(this, event);\n }\n\n navigateFrame(element, location) {\n this.debug(\"navigate-frame\", this.element.src, location);\n\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 (this.element.hasAttribute(\"busy\")) {\n this.debug(\"clearing src to cancel turbo request\");\n this.element.src = \"\";\n }\n\n if (this.element.src === location) {\n this.debug(\"skipping navigate as already on location\");\n return false;\n }\n\n if (this.element.src !== window.location.href) {\n console.warn(\"kpop: frame src doesn't match window\", this.element.src, window.location.href, location);\n // clear src so that turbo doesn't cache the frame in a loading state\n this.element.delegate.ignoringChangesToAttribute(\"src\", (() => {\n this.element.src = \"\";\n this.element.delegate.complete = false;\n }));\n }\n\n // Delay turbo's navigateFrame until next tick to let the src change settle.\n return Promise.resolve(true);\n }\n\n beforeFrameRender(event) {\n this.debug(\"before-frame-render\", event.detail.newFrame.baseURI);\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 = (stream) => {\n (this.dismissing || Promise.resolve()).then(() => {\n this.debug(\"stream-render\", stream);\n resume(stream);\n });\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 // ignore unless we're open\n if (!this.isOpen) return;\n\n this.modal.beforeVisit(this, e);\n }\n\n frameLoad(event) {\n this.debug(\"frame-load\");\n\n return this.open(new FrameModal(this.element.id, this.element.src), {\n animate: true,\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 const scrim = this.scrimConnected && this.scrimOutlet;\n\n this.modal = modal;\n this.openValue = true;\n\n await modal.open({ animate });\n await scrim?.show({ animate });\n\n delete this.opening;\n\n this.debug(\"open-end\");\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 if (DEBUG) debugger;\n }\n\n await this.scrimOutlet.hide({ animate });\n await this.modal?.dismiss();\n\n this.openValue = false;\n this.modal = null;\n delete this.dismissing;\n\n this.debug(\"dismiss-end\");\n }\n\n async #nextFrame(callback) {\n return new Promise(window.requestAnimationFrame).then(callback);\n }\n\n debug(event, ...args) {\n if (DEBUG) console.debug(`FrameController:${event}`, ...args);\n }\n}\n\n/**\n * Monkey patch for Turbo#FrameController.\n *\n * Intercept calls to navigateFrame(element, location) and ensures that src is\n * cleared if the frame is busy so that we don't restore an in-progress src on\n * restoration visits.\n *\n * See Turbo issue: https://github.com/hotwired/turbo/issues/1055\n *\n * @param frameElement turbo-frame element\n */\nfunction installNavigationInterception(frameElement, controller) {\n if (controller._navigateFrame === undefined) {\n controller._navigateFrame = controller.navigateFrame;\n controller.navigateFrame = async (element, location) => {\n const navigate = await frameElement.kpop?.navigateFrame(element, location);\n return navigate && controller._navigateFrame(element, location);\n };\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nimport DEBUG from \"../debug\";\n\n/**\n * Scrim controller wraps an element that creates a whole page layer.\n * It is intended to be used behind a modal or nav drawer.\n *\n * If the Scrim element receives a click event, it automatically triggers \"scrim:hide\".\n *\n * You can show and hide the scrim programmatically by calling show/hide on the controller, e.g. using an outlet.\n *\n * If you need to respond to the scrim showing or hiding you should subscribe to \"scrim:show\" and \"scrim:hide\".\n */\nexport default class ScrimController extends Controller {\n static values = {\n open: Boolean,\n captive: Boolean,\n zIndex: Number,\n };\n\n connect() {\n if (DEBUG) console.debug(\"scrim:connect\");\n\n this.defaultZIndexValue = this.zIndexValue;\n this.defaultCaptiveValue = this.captiveValue;\n\n this.element.scrim = this;\n }\n\n disconnect() {\n if (DEBUG) console.debug(\"scrim:disconnect\");\n\n delete this.element.scrim;\n }\n\n async show({\n captive = this.defaultCaptiveValue,\n zIndex = this.defaultZIndexValue,\n top = window.scrollY,\n animate = true,\n } = {}) {\n if (DEBUG) console.debug(\"scrim:before-show\");\n\n // hide the scrim before opening the new one if it's already open\n if (this.openValue) {\n await this.hide({ animate });\n }\n\n // update internal state\n this.openValue = true;\n\n // notify listeners of pending request\n this.dispatch(\"show\", { bubbles: true });\n\n if (DEBUG) console.debug(\"scrim:show-start\");\n\n // update state, perform style updates\n this.#show(captive, zIndex, top);\n\n if (animate) {\n // animate opening\n // this will trigger an animationEnd event via CSS that completes the open\n this.element.dataset.showAnimating = \"\";\n\n await new Promise((resolve) => {\n this.element.addEventListener(\"animationend\", () => resolve(), {\n once: true,\n });\n });\n\n delete this.element.dataset.showAnimating;\n }\n\n if (DEBUG) console.debug(\"scrim:show-end\");\n }\n\n async hide({ animate = true } = {}) {\n if (!this.openValue || this.element.dataset.hideAnimating) return;\n\n if (DEBUG) console.debug(\"scrim:before-hide\");\n\n // notify listeners of pending request\n this.dispatch(\"hide\", { bubbles: true });\n\n if (DEBUG) console.debug(\"scrim:hide-start\");\n\n if (animate) {\n // set animation state\n // this will trigger an animationEnd event via CSS that completes the hide\n this.element.dataset.hideAnimating = \"\";\n\n await new Promise((resolve) => {\n this.element.addEventListener(\"animationend\", () => resolve(), {\n once: true,\n });\n });\n\n delete this.element.dataset.hideAnimating;\n }\n\n this.#hide();\n\n this.openValue = false;\n\n if (DEBUG) console.debug(\"scrim:hide-end\");\n }\n\n dismiss(event) {\n if (DEBUG) console.debug(\"scrim:dismiss\");\n\n if (!this.captiveValue) this.dispatch(\"dismiss\", { bubbles: true });\n }\n\n escape(event) {\n if (\n event.key === \"Escape\" &&\n !this.captiveValue &&\n !event.defaultPrevented\n ) {\n this.dispatch(\"dismiss\", { bubbles: true });\n }\n }\n\n /**\n * Clips body to viewport size and sets the z-index\n */\n #show(captive, zIndex, top) {\n this.captiveValue = captive;\n this.zIndexValue = zIndex;\n this.scrollY = top;\n\n this.previousPosition = document.body.style.position;\n this.previousTop = document.body.style.top;\n\n this.element.style.zIndex = this.zIndexValue;\n document.body.style.top = `-${top}px`;\n document.body.style.position = \"fixed\";\n }\n\n /**\n * Unclips body from viewport size and unsets the z-index\n */\n #hide() {\n this.captiveValue = this.defaultCaptiveValue;\n this.zIndexValue = this.defaultZIndexValue;\n\n resetStyle(this.element, \"z-index\", null);\n resetStyle(document.body, \"position\", null);\n resetStyle(document.body, \"top\", null);\n\n window.scrollTo({ left: 0, top: this.scrollY, behavior: \"instant\" });\n\n delete this.scrollY;\n delete this.previousPosition;\n delete this.previousTop;\n }\n}\n\nfunction resetStyle(element, property, previousValue) {\n if (previousValue) {\n element.style.setProperty(property, previousValue);\n } else {\n element.style.removeProperty(property);\n }\n}\n","import { Turbo } from \"@hotwired/turbo-rails\";\n\nimport { Modal } from \"./modal\";\n\nexport class StreamModal extends Modal {\n constructor(id, action) {\n super(id);\n\n this.action = action;\n }\n\n async open() {\n await super.open();\n\n window.history.pushState({ kpop: true, id: this.id }, \"\", window.location);\n }\n\n async dismiss() {\n await super.dismiss();\n\n if (this.isCurrentLocation) {\n await this.pop(\"popstate\", () => window.history.back());\n }\n\n this.frameElement.innerHTML = \"\";\n }\n\n beforeVisit(frame, e) {\n super.beforeVisit(frame, e);\n\n e.preventDefault();\n\n frame.dismiss({ animate: false }).then(() => {\n Turbo.visit(e.detail.url);\n\n this.debug(\"before-visit-end\");\n });\n }\n\n popstate(frame, e) {\n super.popstate(frame, e);\n\n frame.dismiss({ animate: true, reason: \"popstate\" });\n }\n\n get isCurrentLocation() {\n return window.history.state?.kpop && window.history.state?.id === this.id;\n }\n}\n","import DEBUG from \"../debug\";\n\nexport class StreamRenderer {\n constructor(frame, action) {\n this.frame = frame;\n this.action = action;\n }\n\n render() {\n if (DEBUG) console.debug(\"stream-renderer:render\");\n this.frame.src = \"\";\n this.frame.innerHTML = \"\";\n this.frame.append(this.action.templateContent);\n }\n}\n","import { Turbo } from \"@hotwired/turbo-rails\";\n\nimport DEBUG from \"./debug\";\n\nimport { StreamModal } from \"./modals/stream_modal\";\nimport { StreamRenderer } from \"./utils/stream_renderer\";\n\nfunction kpop(action) {\n return action.targetElements[0]?.kpop;\n}\n\nTurbo.StreamActions.kpop_open = function () {\n const animate = !kpop(this).openValue;\n\n kpop(this)\n ?.dismiss({ animate, reason: \"before-turbo-stream\" })\n .then(() => {\n new StreamRenderer(this.targetElements[0], this).render();\n kpop(this)?.open(new StreamModal(this.target, this), { animate });\n });\n};\n\nTurbo.StreamActions.kpop_dismiss = function () {\n kpop(this)?.dismiss({ reason: \"turbo_stream.kpop.dismiss\" });\n};\n\nTurbo.StreamActions.kpop_redirect_to = function () {\n if (this.dataset.turboFrame === this.target) {\n if (DEBUG)\n console.debug(\n `kpop: redirecting ${this.target} to ${this.getAttribute(\"href\")}`\n );\n const a = document.createElement(\"A\");\n a.setAttribute(\"data-turbo-action\", \"replace\");\n this.targetElements[0].delegate.navigateFrame(a, this.getAttribute(\"href\"));\n } else {\n if (DEBUG)\n console.debug(`kpop: redirecting to ${this.getAttribute(\"href\")}`);\n Turbo.visit(this.getAttribute(\"href\"), {\n action: this.dataset.turboAction,\n });\n }\n};\n","import FrameController from \"../kpop/controllers/frame_controller\";\nimport ModalController from \"../kpop/controllers/modal_controller\";\nimport ScrimController from \"../kpop/controllers/scrim_controller\";\n\nimport \"./turbo_actions\";\n\nconst Definitions = [\n { identifier: \"kpop--frame\", controllerConstructor: FrameController },\n { identifier: \"kpop--modal\", controllerConstructor: ModalController },\n { identifier: \"scrim\", controllerConstructor: ScrimController },\n];\n\nexport { Definitions as default };\n","import { Controller } from \"@hotwired/stimulus\";\n\nimport DEBUG from \"../debug\";\n\nexport default class Kpop__ModalController extends Controller {\n static values = {\n fallback_location: String,\n layout: String,\n };\n\n connect() {\n this.debug(\"connect\");\n\n if (this.layoutValue) {\n document.querySelector(\"#kpop\").classList.toggle(this.layoutValue, true);\n }\n }\n\n disconnect() {\n this.debug(\"disconnect\");\n\n if (this.layoutValue) {\n document.querySelector(\"#kpop\").classList.toggle(this.layoutValue, false);\n }\n }\n\n debug(event, ...args) {\n if (DEBUG) console.debug(`ModalController:${event}`, ...args);\n }\n}\n"],"names":["Modal","constructor","id","this","open","debug","dismiss","beforeVisit","frame","e","detail","url","popstate","state","pop","event","callback","promise","Promise","resolve","window","addEventListener","once","frameElement","document","getElementById","modalElement","querySelector","currentLocationValue","dataset","fallbackLocationValue","isCurrentLocation","history","turbo","Turbo","session","location","href","src","args","ContentModal","super","visitStarted","visit","scrimOutlet","hide","animate","URL","toString","baseURI","FrameModal","back","preventDefault","then","Kpop__FrameController","Controller","static","Boolean","connect","controller","element","kpop","undefined","delegate","_navigateFrame","navigateFrame","async","complete","pathname","disconnect","modal","scrimOutletConnected","scrim","scrimConnected","openValue","show","openValueChanged","parentElement","style","display","isOpen","opening","nextFrame","reason","dismissing","hasAttribute","console","warn","ignoringChangesToAttribute","beforeFrameRender","newFrame","resume","beforeStreamRender","render","stream","frameLoad","isConnected","requestAnimationFrame","ScrimController","captive","zIndex","Number","defaultZIndexValue","zIndexValue","defaultCaptiveValue","captiveValue","top","scrollY","dispatch","bubbles","showAnimating","hideAnimating","escape","key","defaultPrevented","previousPosition","body","position","previousTop","resetStyle","scrollTo","left","behavior","property","previousValue","setProperty","removeProperty","StreamModal","action","pushState","innerHTML","StreamRenderer","append","templateContent","targetElements","StreamActions","kpop_open","target","kpop_dismiss","kpop_redirect_to","turboFrame","a","createElement","setAttribute","getAttribute","turboAction","Definitions","identifier","controllerConstructor","FrameController","fallback_location","String","layout","layoutValue","classList","toggle"],"mappings":"8FAIO,MAAMA,EACX,WAAAC,CAAYC,GACVC,KAAKD,GAAKA,CACX,CAED,UAAME,GACJD,KAAKE,MAAM,OACZ,CAED,aAAMC,GACJH,KAAKE,MAAM,UACZ,CAED,WAAAE,CAAYC,EAAOC,GACjBN,KAAKE,MAAM,eAAgBI,EAAEC,OAAOC,IACrC,CAED,QAAAC,CAASJ,EAAOC,GACdN,KAAKE,MAAM,WAAYI,EAAEI,MAC1B,CAED,SAAMC,CAAIC,EAAOC,GACfb,KAAKE,MAAM,OAEX,MAAMY,EAAU,IAAIC,SAASC,IAC3BC,OAAOC,iBACLN,GACA,KACEI,GAAS,GAEX,CAAEG,MAAM,GACT,IAKH,OAFAN,IAEOC,CACR,CAED,gBAAIM,GACF,OAAOC,SAASC,eAAetB,KAAKD,GACrC,CAED,gBAAIwB,GACF,OAAOvB,KAAKoB,cAAcI,cAAc,mCACzC,CAED,wBAAIC,GACF,OAAOzB,KAAKuB,cAAcG,QAAQ,mCAAqC,GACxE,CAED,yBAAIC,GACF,OAAO3B,KAAKuB,cAAcG,QAAQ,oCAAsC,GACzE,CAED,qBAAIE,GACF,OACEX,OAAOY,QAAQnB,OAAOoB,OAASC,EAAMC,QAAQC,SAASC,OAASlC,KAAKmC,GAEvE,CAED,KAAAjC,CAAMU,KAAUwB,GAEf,EC/DI,MAAMC,UAAqBxC,EAChC,WAAAC,CAAYC,EAAIoC,EAAM,MACpBG,MAAMvC,GAEFoC,IAAKnC,KAAKmC,IAAMA,EACrB,CAED,aAAMhC,GAGJ,SAFMmC,MAAMnC,UAERH,KAAKuC,aACPvC,KAAKE,MAAM,uCADb,CAIA,GAAKF,KAAK4B,kBAKV,OAAO5B,KAAKW,IAAI,cAAc,KAC5BX,KAAKE,MAAM,cAAeF,KAAK2B,uBAC/BI,EAAMS,MAAMxC,KAAK2B,sBAAsB,IANvC3B,KAAKE,MAAM,yCAFZ,CAYF,CAED,WAAAE,CAAYC,EAAOC,GACjBgC,MAAMlC,YAAYC,EAAOC,GAEzBN,KAAKuC,cAAe,EAEpBlC,EAAMoC,YAAYC,KAAK,CAAEC,SAAS,GACnC,CAED,OAAIR,GACF,OAAO,IAAIS,IACT5C,KAAKyB,qBAAqBoB,WAC1BxB,SAASyB,SACTD,UACH,ECxCI,MAAME,UAAmBlD,EAC9B,WAAAC,CAAYC,EAAIoC,GACdG,MAAMvC,GACNC,KAAKmC,IAAMA,CACZ,CAED,aAAMhC,SACEmC,MAAMnC,UAEPH,KAAK4B,wBAGF5B,KAAKW,IAAI,cAAc,IAAMM,OAAOY,QAAQmB,SAFlDhD,KAAKE,MAAM,yCAMd,CAED,WAAAE,CAAYC,EAAOC,GACjBgC,MAAMlC,YAAYC,EAAOC,GAEzBA,EAAE2C,iBAEF5C,EAAMF,QAAQ,CAAEwC,SAAS,IAASO,MAAK,KACrCnB,EAAMS,MAAMlC,EAAEC,OAAOC,KAErBR,KAAKE,MAAM,mBAAmB,GAEjC,CAED,QAAAO,CAASJ,EAAOC,GACdgC,MAAM7B,SAASJ,EAAOC,GAGtBD,EAAMoC,YAAYC,KAAK,CAAEC,SAAS,GACnC,ECjCY,MAAMQ,UAA8BC,EACjDC,eAAiB,CAAC,SAClBA,eAAiB,CAAC,SAClBA,cAAgB,CACdpD,KAAMqD,SAGR,OAAAC,GAyNF,IAAuCnC,EAAcoC,EAlNjD,GANAxD,KAAKE,MAAM,UAAWF,KAAKyD,QAAQtB,KAEnCnC,KAAKyD,QAAQC,KAAO1D,KAsNeoB,EArNLpB,KAAKyD,aAsNHE,KADiBH,EArNLxD,KAAKyD,QAAQG,UAsN5CC,iBACbL,EAAWK,eAAiBL,EAAWM,cACvCN,EAAWM,cAAgBC,MAAON,EAASxB,UAClBb,EAAasC,MAAMI,cAAcL,EAASxB,KAC9CuB,EAAWK,eAAeJ,EAASxB,IAvNpDjC,KAAKyD,QAAQtB,KAAOnC,KAAKyD,QAAQO,SACnChE,KAAKE,MAAM,kBAAmBF,KAAKyD,QAAQtB,KAC3CnC,KAAKC,KAAK,IAAI8C,EAAW/C,KAAKyD,QAAQ1D,GAAIC,KAAKyD,QAAQtB,KAAM,CAC3DQ,SAAS,QAEN,CACW3C,KAAKyD,QAAQjC,cAC3B,sCAGAxB,KAAKE,MAAM,oBAAqBe,OAAOgB,SAASgC,UAChDjE,KAAKC,KAAK,IAAIoC,EAAarC,KAAKyD,QAAQ1D,IAAK,CAAE4C,SAAS,IAE3D,CACF,CAED,UAAAuB,GACElE,KAAKE,MAAM,qBAEJF,KAAKyD,QAAQC,YACb1D,KAAKmE,KACb,CAED,oBAAAC,CAAqBC,GACnBrE,KAAKE,MAAM,mBAEXF,KAAKsE,gBAAiB,EAElBtE,KAAKuE,UACPF,EAAMG,KAAK,CAAE7B,SAAS,IAEtB0B,EAAM3B,KAAK,CAAEC,SAAS,GAEzB,CAED,gBAAA8B,CAAiBxE,GACfD,KAAKE,MAAM,eAAgBD,GAE3BD,KAAKyD,QAAQiB,cAAcC,MAAMC,QAAU3E,EAAO,OAAS,MAC5D,CAED,UAAMA,CAAKkE,GAAOxB,QAAEA,GAAU,GAAS,CAAA,GACrC,OAAI3C,KAAK6E,QACP7E,KAAKE,MAAM,6BACXF,KAAKmE,QAAUA,GACR,GAGDnE,KAAK8E,UAAY9E,MAAK+E,GAAW,IACvC/E,MAAKC,EAAMkE,EAAO,CAAExB,aAEvB,CAED,aAAMxC,EAAQwC,QAAEA,GAAU,EAAIqC,OAAEA,EAAS,IAAO,IAC9C,OAAKhF,KAAK6E,OAKF7E,KAAKiF,aAAejF,MAAK+E,GAAW,IAC1C/E,MAAKG,EAAS,CAAEwC,UAASqC,cALzBhF,KAAKE,MAAM,mCACJ,EAMV,CAID,QAAAO,CAASG,GACPZ,KAAKmE,OAAO1D,SAAST,KAAMY,EAC5B,CAED,aAAAkD,CAAcL,EAASxB,GAWrB,OAVAjC,KAAKE,MAAM,iBAAkBF,KAAKyD,QAAQtB,IAAKF,GAK3CjC,KAAKyD,QAAQyB,aAAa,UAC5BlF,KAAKE,MAAM,wCACXF,KAAKyD,QAAQtB,IAAM,IAGjBnC,KAAKyD,QAAQtB,MAAQF,GACvBjC,KAAKE,MAAM,6CACJ,IAGLF,KAAKyD,QAAQtB,MAAQlB,OAAOgB,SAASC,OACvCiD,QAAQC,KAAK,uCAAwCpF,KAAKyD,QAAQtB,IAAKlB,OAAOgB,SAASC,KAAMD,GAE7FjC,KAAKyD,QAAQG,SAASyB,2BAA2B,OAAK,KACpDrF,KAAKyD,QAAQtB,IAAM,GACnBnC,KAAKyD,QAAQG,SAASI,UAAW,CAClC,KAIIjD,QAAQC,SAAQ,GACxB,CAED,iBAAAsE,CAAkB1E,GAChBZ,KAAKE,MAAM,sBAAuBU,EAAML,OAAOgF,SAASzC,SAExDlC,EAAMqC,iBAENjD,KAAKG,QAAQ,CAAEwC,SAAS,EAAMqC,OAAQ,wBAAyB9B,MAAK,KAClElD,KAAKE,MAAM,sBAAuBU,EAAML,OAAOgF,SAASzC,SACxDlC,EAAML,OAAOiF,QAAQ,GAExB,CAED,kBAAAC,CAAmB7E,GACjBZ,KAAKE,MAAM,uBAAwBU,EAAML,QAEzC,MAAMiF,EAAS5E,EAAML,OAAOmF,OAK5B9E,EAAML,OAAOmF,OAAUC,KACpB3F,KAAKiF,YAAclE,QAAQC,WAAWkC,MAAK,KAC1ClD,KAAKE,MAAM,gBAAiByF,GAC5BH,EAAOG,EAAO,GACd,CAEL,CAED,WAAAvF,CAAYE,GACVN,KAAKE,MAAM,eAAgBI,EAAEC,OAAOC,KAGhCF,EAAEC,OAAOC,MAAQR,KAAKyD,QAAQtB,KAG7BnC,KAAK6E,QAEV7E,KAAKmE,MAAM/D,YAAYJ,KAAMM,EAC9B,CAED,SAAAsF,CAAUhF,GAGR,OAFAZ,KAAKE,MAAM,cAEJF,KAAKC,KAAK,IAAI8C,EAAW/C,KAAKyD,QAAQ1D,GAAIC,KAAKyD,QAAQtB,KAAM,CAClEQ,SAAS,GAEZ,CAED,UAAIkC,GACF,OAAO7E,KAAKuE,YAAcvE,KAAKiF,UAChC,CAED,OAAMhF,CAAMkE,GAAOxB,QAAEA,GAAU,GAAS,CAAA,GACtC3C,KAAKE,MAAM,aAAc,CAAEyC,YAE3B,MAAM0B,EAAQrE,KAAKsE,gBAAkBtE,KAAKyC,YAE1CzC,KAAKmE,MAAQA,EACbnE,KAAKuE,WAAY,QAEXJ,EAAMlE,KAAK,CAAE0C,kBACb0B,GAAOG,KAAK,CAAE7B,oBAEb3C,KAAK8E,QAEZ9E,KAAKE,MAAM,WACZ,CAED,OAAMC,EAASwC,QAAEA,GAAU,EAAIqC,OAAEA,EAAS,IAAO,IAC/ChF,KAAKE,MAAM,gBAAiB,CAAEyC,UAASqC,WAGlChF,KAAKyD,QAAQoC,aAKb7F,KAAKmE,OACRgB,QAAQC,KAAK,kCAITpF,KAAKyC,YAAYC,KAAK,CAAEC,kBACxB3C,KAAKmE,OAAOhE,WAElBH,KAAKuE,WAAY,EACjBvE,KAAKmE,MAAQ,YACNnE,KAAKiF,WAEZjF,KAAKE,MAAM,gBAhBTF,KAAKE,MAAM,iCAiBd,CAED,OAAM6E,CAAWlE,GACf,OAAO,IAAIE,QAAQE,OAAO6E,uBAAuB5C,KAAKrC,EACvD,CAED,KAAAX,CAAMU,KAAUwB,GAEf,EC1MY,MAAM2D,UAAwB3C,EAC3CC,cAAgB,CACdpD,KAAMqD,QACN0C,QAAS1C,QACT2C,OAAQC,QAGV,OAAA3C,GAGEvD,KAAKmG,mBAAqBnG,KAAKoG,YAC/BpG,KAAKqG,oBAAsBrG,KAAKsG,aAEhCtG,KAAKyD,QAAQY,MAAQrE,IACtB,CAED,UAAAkE,UAGSlE,KAAKyD,QAAQY,KACrB,CAED,UAAMG,EAAKwB,QACTA,EAAUhG,KAAKqG,oBAAmBJ,OAClCA,EAASjG,KAAKmG,mBAAkBI,IAChCA,EAAMtF,OAAOuF,QAAO7D,QACpBA,GAAU,GACR,IAIE3C,KAAKuE,iBACDvE,KAAK0C,KAAK,CAAEC,YAIpB3C,KAAKuE,WAAY,EAGjBvE,KAAKyG,SAAS,OAAQ,CAAEC,SAAS,IAKjC1G,MAAKwE,EAAMwB,EAASC,EAAQM,GAExB5D,IAGF3C,KAAKyD,QAAQ/B,QAAQiF,cAAgB,SAE/B,IAAI5F,SAASC,IACjBhB,KAAKyD,QAAQvC,iBAAiB,gBAAgB,IAAMF,KAAW,CAC7DG,MAAM,GACN,WAGGnB,KAAKyD,QAAQ/B,QAAQiF,cAI/B,CAED,UAAMjE,EAAKC,QAAEA,GAAU,GAAS,CAAA,GACzB3C,KAAKuE,YAAavE,KAAKyD,QAAQ/B,QAAQkF,gBAK5C5G,KAAKyG,SAAS,OAAQ,CAAEC,SAAS,IAI7B/D,IAGF3C,KAAKyD,QAAQ/B,QAAQkF,cAAgB,SAE/B,IAAI7F,SAASC,IACjBhB,KAAKyD,QAAQvC,iBAAiB,gBAAgB,IAAMF,KAAW,CAC7DG,MAAM,GACN,WAGGnB,KAAKyD,QAAQ/B,QAAQkF,eAG9B5G,MAAK0C,IAEL1C,KAAKuE,WAAY,EAGlB,CAED,OAAApE,CAAQS,GAGDZ,KAAKsG,cAActG,KAAKyG,SAAS,UAAW,CAAEC,SAAS,GAC7D,CAED,MAAAG,CAAOjG,GAEW,WAAdA,EAAMkG,KACL9G,KAAKsG,cACL1F,EAAMmG,kBAEP/G,KAAKyG,SAAS,UAAW,CAAEC,SAAS,GAEvC,CAKD,EAAAlC,CAAMwB,EAASC,EAAQM,GACrBvG,KAAKsG,aAAeN,EACpBhG,KAAKoG,YAAcH,EACnBjG,KAAKwG,QAAUD,EAEfvG,KAAKgH,iBAAmB3F,SAAS4F,KAAKtC,MAAMuC,SAC5ClH,KAAKmH,YAAc9F,SAAS4F,KAAKtC,MAAM4B,IAEvCvG,KAAKyD,QAAQkB,MAAMsB,OAASjG,KAAKoG,YACjC/E,SAAS4F,KAAKtC,MAAM4B,IAAM,IAAIA,MAC9BlF,SAAS4F,KAAKtC,MAAMuC,SAAW,OAChC,CAKD,EAAAxE,GACE1C,KAAKsG,aAAetG,KAAKqG,oBACzBrG,KAAKoG,YAAcpG,KAAKmG,mBAExBiB,EAAWpH,KAAKyD,QAAS,UAAW,MACpC2D,EAAW/F,SAAS4F,KAAM,WAAY,MACtCG,EAAW/F,SAAS4F,KAAM,MAAO,MAEjChG,OAAOoG,SAAS,CAAEC,KAAM,EAAGf,IAAKvG,KAAKwG,QAASe,SAAU,mBAEjDvH,KAAKwG,eACLxG,KAAKgH,wBACLhH,KAAKmH,WACb,EAGH,SAASC,EAAW3D,EAAS+D,EAAUC,GACjCA,EACFhE,EAAQkB,MAAM+C,YAAYF,EAAUC,GAEpChE,EAAQkB,MAAMgD,eAAeH,EAEjC,CCjKO,MAAMI,UAAoB/H,EAC/B,WAAAC,CAAYC,EAAI8H,GACdvF,MAAMvC,GAENC,KAAK6H,OAASA,CACf,CAED,UAAM5H,SACEqC,MAAMrC,OAEZgB,OAAOY,QAAQiG,UAAU,CAAEpE,MAAM,EAAM3D,GAAIC,KAAKD,IAAM,GAAIkB,OAAOgB,SAClE,CAED,aAAM9B,SACEmC,MAAMnC,UAERH,KAAK4B,yBACD5B,KAAKW,IAAI,YAAY,IAAMM,OAAOY,QAAQmB,SAGlDhD,KAAKoB,aAAa2G,UAAY,EAC/B,CAED,WAAA3H,CAAYC,EAAOC,GACjBgC,MAAMlC,YAAYC,EAAOC,GAEzBA,EAAE2C,iBAEF5C,EAAMF,QAAQ,CAAEwC,SAAS,IAASO,MAAK,KACrCnB,EAAMS,MAAMlC,EAAEC,OAAOC,KAErBR,KAAKE,MAAM,mBAAmB,GAEjC,CAED,QAAAO,CAASJ,EAAOC,GACdgC,MAAM7B,SAASJ,EAAOC,GAEtBD,EAAMF,QAAQ,CAAEwC,SAAS,EAAMqC,OAAQ,YACxC,CAED,qBAAIpD,GACF,OAAOX,OAAOY,QAAQnB,OAAOgD,MAAQzC,OAAOY,QAAQnB,OAAOX,KAAOC,KAAKD,EACxE,EC7CI,MAAMiI,EACX,WAAAlI,CAAYO,EAAOwH,GACjB7H,KAAKK,MAAQA,EACbL,KAAK6H,OAASA,CACf,CAED,MAAAnC,GAEE1F,KAAKK,MAAM8B,IAAM,GACjBnC,KAAKK,MAAM0H,UAAY,GACvB/H,KAAKK,MAAM4H,OAAOjI,KAAK6H,OAAOK,gBAC/B,ECNH,SAASxE,EAAKmE,GACZ,OAAOA,EAAOM,eAAe,IAAIzE,IACnC,CAEA3B,EAAMqG,cAAcC,UAAY,WAC9B,MAAM1F,GAAWe,EAAK1D,MAAMuE,UAE5Bb,EAAK1D,OACDG,QAAQ,CAAEwC,UAASqC,OAAQ,wBAC5B9B,MAAK,KACJ,IAAI8E,EAAehI,KAAKmI,eAAe,GAAInI,MAAM0F,SACjDhC,EAAK1D,OAAOC,KAAK,IAAI2H,EAAY5H,KAAKsI,OAAQtI,MAAO,CAAE2C,WAAU,GAEvE,EAEAZ,EAAMqG,cAAcG,aAAe,WACjC7E,EAAK1D,OAAOG,QAAQ,CAAE6E,OAAQ,6BAChC,EAEAjD,EAAMqG,cAAcI,iBAAmB,WACrC,GAAIxI,KAAK0B,QAAQ+G,aAAezI,KAAKsI,OAAQ,CAK3C,MAAMI,EAAIrH,SAASsH,cAAc,KACjCD,EAAEE,aAAa,oBAAqB,WACpC5I,KAAKmI,eAAe,GAAGvE,SAASE,cAAc4E,EAAG1I,KAAK6I,aAAa,QACvE,MAGI9G,EAAMS,MAAMxC,KAAK6I,aAAa,QAAS,CACrChB,OAAQ7H,KAAK0B,QAAQoH,aAG3B,ECpCK,MAACC,EAAc,CAClB,CAAEC,WAAY,cAAeC,sBAAuBC,GACpD,CAAEF,WAAY,cAAeC,sBCJhB,cAAoC7F,EACjDC,cAAgB,CACd8F,kBAAmBC,OACnBC,OAAQD,QAGV,OAAA7F,GACEvD,KAAKE,MAAM,WAEPF,KAAKsJ,aACPjI,SAASG,cAAc,SAAS+H,UAAUC,OAAOxJ,KAAKsJ,aAAa,EAEtE,CAED,UAAApF,GACElE,KAAKE,MAAM,cAEPF,KAAKsJ,aACPjI,SAASG,cAAc,SAAS+H,UAAUC,OAAOxJ,KAAKsJ,aAAa,EAEtE,CAED,KAAApJ,CAAMU,KAAUwB,GAEf,IDnBD,CAAE4G,WAAY,QAASC,sBAAuBlD"}
@@ -12,6 +12,8 @@
12
12
  background-color: white;
13
13
  border: 1px solid black;
14
14
  border-radius: $border-radius;
15
+ overflow: hidden;
16
+ max-height: var(--max-height);
15
17
  }
16
18
 
17
19
  .kpop-title-bar {
@@ -17,7 +17,7 @@
17
17
  --closing-animation: slide-out-bottom;
18
18
  --min-width: 100dvw;
19
19
  --max-width: 100dvw;
20
- --min-height: 30dvh;
20
+ --min-height: 50dvh;
21
21
  --max-height: calc(100dvh - 1.5rem);
22
22
  }
23
23
  }
@@ -15,7 +15,7 @@ export default class Kpop__FrameController extends Controller {
15
15
  this.debug("connect", this.element.src);
16
16
 
17
17
  this.element.kpop = this;
18
- installNavigationInterception(this.element);
18
+ installNavigationInterception(this.element, this.element.delegate);
19
19
 
20
20
  // restoration visit
21
21
  if (this.element.src && this.element.complete) {
@@ -95,11 +95,26 @@ export default class Kpop__FrameController extends Controller {
95
95
  // the current request (if any) by clearing the src.
96
96
  // Known issue: this won't work if the frame was previously rendering a useful src.
97
97
  if (this.element.hasAttribute("busy")) {
98
+ this.debug("clearing src to cancel turbo request");
98
99
  this.element.src = "";
99
100
  }
100
101
 
102
+ if (this.element.src === location) {
103
+ this.debug("skipping navigate as already on location");
104
+ return false;
105
+ }
106
+
107
+ if (this.element.src !== window.location.href) {
108
+ console.warn("kpop: frame src doesn't match window", this.element.src, window.location.href, location);
109
+ // clear src so that turbo doesn't cache the frame in a loading state
110
+ this.element.delegate.ignoringChangesToAttribute("src", (() => {
111
+ this.element.src = "";
112
+ this.element.delegate.complete = false;
113
+ }));
114
+ }
115
+
101
116
  // Delay turbo's navigateFrame until next tick to let the src change settle.
102
- return Promise.resolve();
117
+ return Promise.resolve(true);
103
118
  }
104
119
 
105
120
  beforeFrameRender(event) {
@@ -213,16 +228,12 @@ export default class Kpop__FrameController extends Controller {
213
228
  *
214
229
  * @param frameElement turbo-frame element
215
230
  */
216
- function installNavigationInterception(frameElement) {
217
- if (frameElement.delegate._navigateFrame === undefined) {
218
- frameElement.delegate._navigateFrame = frameElement.delegate.navigateFrame;
219
- frameElement.delegate.navigateFrame = async (element, location) => {
220
- await frameElement.kpop?.navigateFrame(element, location);
221
- return frameElement.delegate._navigateFrame.call(
222
- frameElement.delegate,
223
- element,
224
- location
225
- );
231
+ function installNavigationInterception(frameElement, controller) {
232
+ if (controller._navigateFrame === undefined) {
233
+ controller._navigateFrame = controller.navigateFrame;
234
+ controller.navigateFrame = async (element, location) => {
235
+ const navigate = await frameElement.kpop?.navigateFrame(element, location);
236
+ return navigate && controller._navigateFrame(element, location);
226
237
  };
227
238
  }
228
239
  }
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Katalyst
4
4
  module Kpop
5
- VERSION = "3.0.0.beta.6"
5
+ VERSION = "3.0.0.beta.7"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: katalyst-kpop
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.beta.6
4
+ version: 3.0.0.beta.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katalyst Interactive
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-31 00:00:00.000000000 Z
11
+ date: 2023-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: html-attributes-utils