From bedcad6ab2d39ab8ae74b70803fe92fa09d07db3 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 8 Oct 2020 22:31:58 -0400 Subject: [PATCH] Update the Modal class to support non-jQuery modals (#900) --- ext/bg/js/settings/modal.js | 44 ++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/ext/bg/js/settings/modal.js b/ext/bg/js/settings/modal.js index 42a511ca..f9a8ec6b 100644 --- a/ext/bg/js/settings/modal.js +++ b/ext/bg/js/settings/modal.js @@ -20,6 +20,9 @@ class Modal extends EventDispatcher { super(); this._node = node; this._eventListeners = new EventListenerCollection(); + this._mutationObserver = null; + this._visible = false; + this._visibleClassName = 'modal-container-open'; } get node() { @@ -27,15 +30,31 @@ class Modal extends EventDispatcher { } setVisible(value) { - this._getWrappedNode().modal(value ? 'show' : 'hide'); + if (this._useJqueryModal()) { + this._getWrappedNode().modal(value ? 'show' : 'hide'); + } else { + this._node.classList.toggle(this._visibleClassName, value); + } } on(eventName, callback) { if (eventName === 'visibilityChanged') { - if (this._eventListeners.size === 0) { - const wrappedNode = this._getWrappedNode(); - this._eventListeners.on(wrappedNode, 'hidden.bs.modal', this._onModalHide.bind(this)); - this._eventListeners.on(wrappedNode, 'shown.bs.modal', this._onModalShow.bind(this)); + if (this._useJqueryModal()) { + if (this._eventListeners.size === 0) { + const wrappedNode = this._getWrappedNode(); + this._eventListeners.on(wrappedNode, 'hidden.bs.modal', this._onModalHide.bind(this)); + this._eventListeners.on(wrappedNode, 'shown.bs.modal', this._onModalShow.bind(this)); + } + } else { + if (this._mutationObserver === null) { + this._visible = this._node.classList.contains(this._visibleClassName); + this._mutationObserver = new MutationObserver(this._onMutation.bind(this)); + this._mutationObserver.observe(this._node, { + attributes: true, + attributeFilter: ['class'], + attributeOldValue: true + }); + } } } return super.on(eventName, callback); @@ -44,6 +63,10 @@ class Modal extends EventDispatcher { off(eventName, callback) { const result = super.off(eventName, callback); if (eventName === 'visibilityChanged' && !this.hasListeners(eventName)) { + if (this._mutationObserver !== null) { + this._mutationObserver.disconnect(); + this._mutationObserver = null; + } this._eventListeners.removeAllEventListeners(); } return result; @@ -59,6 +82,17 @@ class Modal extends EventDispatcher { this.trigger('visibilityChanged', {visible: true}); } + _onMutation() { + const visible = this._node.classList.contains(this._visibleClassName); + if (this._visible === visible) { return; } + this._visible = visible; + this.trigger('visibilityChanged', {visible: false}); + } + + _useJqueryModal() { + return (typeof jQuery !== 'undefined'); + } + _getWrappedNode() { return $(this._node); }