From d44c9cf065636d9ecb5c3765441119bdc050bf41 Mon Sep 17 00:00:00 2001 From: David Battersby Date: Mon, 17 Jul 2023 19:55:48 +0800 Subject: [PATCH] FIX: bind selector to event listener callback for lightbox (#22637) Fixes an issue where this.selector value was not binded at the time of adding the event listener. Therefore when someone opens a chat channel that has images, the value of selector would change. I also moved the callback to a named function (rather than the default handleEvent). --- .../discourse/app/services/lightbox.js | 64 +++++++++++-------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/app/assets/javascripts/discourse/app/services/lightbox.js b/app/assets/javascripts/discourse/app/services/lightbox.js index 864de2a7e69..ee7aa73728c 100644 --- a/app/assets/javascripts/discourse/app/services/lightbox.js +++ b/app/assets/javascripts/discourse/app/services/lightbox.js @@ -106,31 +106,6 @@ export default class LightboxService extends Service { return true; } - @bind - handleEvent(event) { - const isLightboxClick = event - .composedPath() - .find( - (element) => - element.matches && - (element.matches(this.selector) || - element.matches("[data-lightbox-trigger]")) - ); - - if (!isLightboxClick) { - return; - } - - event.preventDefault(); - - this.openLightbox({ - container: event.currentTarget, - selector: this.selector, - }); - - event.target.toggleAttribute(SELECTORS.DOCUMENT_LAST_FOCUSED_ELEMENT); - } - @bind async openLightbox({ container, selector }) { const { items, startingIndex } = await processHTML({ container, selector }); @@ -170,8 +145,13 @@ export default class LightboxService extends Service { } const handlerOptions = { capture: true }; - - container.addEventListener("click", this, handlerOptions); + container.addEventListener( + "click", + (event) => { + this.handleClickEvent(event, selector); + }, + handlerOptions + ); this.lightboxClickElements.push({ container, handlerOptions }); } @@ -185,7 +165,11 @@ export default class LightboxService extends Service { this.closeLightbox(); this.lightboxClickElements.forEach(({ container, handlerOptions }) => { - container.removeEventListener("click", this, handlerOptions); + container.removeEventListener( + "click", + this.handleClickEvent, + handlerOptions + ); }); this.lightboxClickElements = []; @@ -251,6 +235,30 @@ export default class LightboxService extends Service { ); } + handleClickEvent(event, trigger) { + const isLightboxClick = event + .composedPath() + .find( + (element) => + element.matches && + (element.matches(trigger) || + element.matches("[data-lightbox-trigger]")) + ); + + if (!isLightboxClick) { + return; + } + + event.preventDefault(); + + this.openLightbox({ + container: event.currentTarget, + selector: trigger, + }); + + event.target.toggleAttribute(SELECTORS.DOCUMENT_LAST_FOCUSED_ELEMENT); + } + willDestroy() { this.#reset(); }