diff --git a/app/assets/javascripts/discourse/app/mixins/card-contents-base.js b/app/assets/javascripts/discourse/app/mixins/card-contents-base.js index bda3d3f11f8..2a1f1b253fa 100644 --- a/app/assets/javascripts/discourse/app/mixins/card-contents-base.js +++ b/app/assets/javascripts/discourse/app/mixins/card-contents-base.js @@ -7,6 +7,7 @@ import { escapeExpression } from "discourse/lib/utilities"; import headerOutletHeights from "discourse/lib/header-outlet-height"; import { inject as service } from "@ember/service"; import { wantsNewWindow } from "discourse/lib/intercept-click"; +import { bind } from "discourse-common/utils/decorators"; const DEFAULT_SELECTOR = "#main-outlet"; @@ -97,35 +98,16 @@ export default Mixin.create({ afterTransition($(this.element), this._hide.bind(this)); const id = this.elementId; const triggeringLinkClass = this.triggeringLinkClass; - const clickOutsideEventName = `mousedown.outside-${id}`; const previewClickEvent = `click.discourse-preview-${id}-${triggeringLinkClass}`; const mobileScrollEvent = "scroll.mobile-card-cloak"; this.setProperties({ boundCardClickHandler: this._cardClickHandler.bind(this), - clickOutsideEventName, previewClickEvent, mobileScrollEvent, }); - $("html") - .off(clickOutsideEventName) - .on(clickOutsideEventName, (e) => { - if (this.visible) { - const $target = $(e.target); - if ( - $target.closest(`[data-${id}]`).data(id) || - $target.closest(`a.${triggeringLinkClass}`).length > 0 || - $target.closest(`#${id}`).length > 0 - ) { - return; - } - - this._close(); - } - - return true; - }); + document.addEventListener("mousedown", this._clickOutsideHandler); _cardClickListenerSelectors.forEach((selector) => { document @@ -336,16 +318,16 @@ export default Mixin.create({ willDestroyElement() { this._super(...arguments); - const clickOutsideEventName = this.clickOutsideEventName; - const previewClickEvent = this.previewClickEvent; - $("html").off(clickOutsideEventName); + document.removeEventListener("mousedown", this._clickOutsideHandler); + _cardClickListenerSelectors.forEach((selector) => { document .querySelector(selector) .removeEventListener("click", this.boundCardClickHandler); }); + const previewClickEvent = this.previewClickEvent; this.appEvents.off(previewClickEvent, this, "_previewClick"); this.appEvents.off( @@ -364,4 +346,22 @@ export default Mixin.create({ target.focus(); } }, + + @bind + _clickOutsideHandler(event) { + if (this.visible) { + const $target = $(event.target); + if ( + $target.closest(`[data-${this.elementId}]`).data(this.elementId) || + $target.closest(`a.${this.triggeringLinkClass}`).length > 0 || + $target.closest(`#${this.elementId}`).length > 0 + ) { + return; + } + + this._close(); + } + + return true; + }, });