From bedcad6ab2d39ab8ae74b70803fe92fa09d07db3 Mon Sep 17 00:00:00 2001
From: toasted-nutbread <toasted-nutbread@users.noreply.github.com>
Date: Thu, 8 Oct 2020 22:31:58 -0400
Subject: 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);
     }
-- 
cgit v1.2.3