Update the Modal class to support non-jQuery modals (#900)

This commit is contained in:
toasted-nutbread 2020-10-08 22:31:58 -04:00 committed by GitHub
parent 41ead7a90a
commit bedcad6ab2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -20,6 +20,9 @@ class Modal extends EventDispatcher {
super(); super();
this._node = node; this._node = node;
this._eventListeners = new EventListenerCollection(); this._eventListeners = new EventListenerCollection();
this._mutationObserver = null;
this._visible = false;
this._visibleClassName = 'modal-container-open';
} }
get node() { get node() {
@ -27,15 +30,31 @@ class Modal extends EventDispatcher {
} }
setVisible(value) { 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) { on(eventName, callback) {
if (eventName === 'visibilityChanged') { if (eventName === 'visibilityChanged') {
if (this._eventListeners.size === 0) { if (this._useJqueryModal()) {
const wrappedNode = this._getWrappedNode(); if (this._eventListeners.size === 0) {
this._eventListeners.on(wrappedNode, 'hidden.bs.modal', this._onModalHide.bind(this)); const wrappedNode = this._getWrappedNode();
this._eventListeners.on(wrappedNode, 'shown.bs.modal', this._onModalShow.bind(this)); 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); return super.on(eventName, callback);
@ -44,6 +63,10 @@ class Modal extends EventDispatcher {
off(eventName, callback) { off(eventName, callback) {
const result = super.off(eventName, callback); const result = super.off(eventName, callback);
if (eventName === 'visibilityChanged' && !this.hasListeners(eventName)) { if (eventName === 'visibilityChanged' && !this.hasListeners(eventName)) {
if (this._mutationObserver !== null) {
this._mutationObserver.disconnect();
this._mutationObserver = null;
}
this._eventListeners.removeAllEventListeners(); this._eventListeners.removeAllEventListeners();
} }
return result; return result;
@ -59,6 +82,17 @@ class Modal extends EventDispatcher {
this.trigger('visibilityChanged', {visible: true}); 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() { _getWrappedNode() {
return $(this._node); return $(this._node);
} }