@cocreate/modal
Version:
A draggable, movable and resizable modal. customizable via attributes, great for popups, alerts, multitasking and displaying multiple views.
239 lines (201 loc) • 6.76 kB
JavaScript
import ModalViewPort from "./viewport.js"
import uuid from '@cocreate/uuid'
import action from '@cocreate/actions';
import observer from '@cocreate/observer';
import socket from '@cocreate/socket-client';
import localStorge from '@cocreate/local-storage';
import './index.css';
function CoCreateModal(id) {
this.viewPort = null;
this.id = id || 'modal-viewport'
this.pageId = uuid.generate();
this.isRoot = this._checkRoot();
if (this.isRoot) {
this.viewPorts = new Map();
this.viewPorts.set(this.pageId, this)
this.modals = new Map();
this.rootId = this.pageId;
this.parentId = this.pageId;
localStorage.setItem('rootId', this.pageId)
} else {
this.pageId = localStorage.getItem('pageId')
let viewPort = window.top.CoCreate.modal.viewPorts
if (viewPort)
viewPort.set(this.pageId, this)
// TODO: can be depreciated if we find a better way to pass rootid and parentid
this.parentId = localStorage.getItem('parentId')
this.rootId = window.top.CoCreate.modal.rootId
}
this._createViewPort();
this._initSocket();
action.init({
name: "openModal",
endEvent: "openModal",
callback: (data) => {
this.open(data.element);
},
});
action.init({
name: "closeModal",
endEvent: "closeModal",
callback: (data) => {
this.modalAction(data.element, 'close');
},
});
action.init({
name: "minMaxModal",
endEvent: "minMaxModal",
callback: (data) => {
this.modalAction(data.element, 'minMax');
},
});
action.init({
name: "parkModal",
endEvent: "parkModal",
callback: (data) => {
this.modalAction(data.element, 'park');
},
});
}
CoCreateModal.prototype = {
_checkRoot: function () {
try {
return window === window.top;
} catch (e) {
return false;
}
},
_createViewPort: function () {
if (this.viewPort)
return true;
let el = document.getElementById(this.id);
if (el) {
this.viewPort = new ModalViewPort(el);
return true;
} else {
return false;
}
},
_initSocket: function () {
const self = this;
socket.listen('modalAction', function (response) {
self.runModalAction(response.data)
})
},
open: function (aTag) {
let attributes = [];
for (let attribute of aTag.attributes)
attributes[attribute.name] = attribute.value
let data = {
src: aTag.getAttribute('modal-src'),
x: aTag.getAttribute('modal-x'),
y: aTag.getAttribute('modal-y'),
width: aTag.getAttribute('modal-width'),
height: aTag.getAttribute('modal-height'),
color: aTag.getAttribute('modal-color'),
header: aTag.getAttribute('modal-header'),
iframe: aTag.getAttribute('modal-iframe'),
attributes: attributes
}
// retrieves absolute path of href
if (data.src) {
let a = document.createElement('a')
a.href = data.src
data.src = a.href
a.remove
}
let openIn = aTag.getAttribute('modal-open') || 'root';
let openId;
switch (openIn) {
case 'parent':
openId = this.parentId;
break;
case 'page':
openId = this.pageId;
break;
case 'root':
openId = this.rootId;
break;
default:
openId = openIn;
break;
}
localStorage.setItem('parentId', openId)
data.type = 'open';
data.parentId = openId;
if (this.isRoot) {
if (this._createViewPort())
this.viewPort._createModal(data);
} else {
let viewPort = window.top.CoCreate.modal.viewPorts.get(openId);
if (viewPort.pageId == data.parentId) {
viewPort.viewPort._createModal(data);
document.dispatchEvent(new CustomEvent('openModal', {
detail: {}
}))
} else {
this.modalAction(btn, 'open', data)
}
}
},
modalAction: function (btn, type, data) {
let json = {
key: CoCreateConfig.key,
organization_id: CoCreateConfig.organization_id,
broadcastSender: true,
method: 'modalAction',
}
if (type == 'open') {
json.data = data
socket.send(json);
} else {
let modalEl = btn.closest('.modal')
let modal
if (modalEl)
modal = this.viewPort.modals.get(modalEl.id || this.pageId)
if (!modal) {
modal = window.top.CoCreate.modal.modals.get(this.pageId);
}
json.data = {
parentId: this.parentId,
pageId: this.pageId,
modal,
type
}
if (modal)
this.runModalAction(json.data)
else
socket.send(json);
}
},
runModalAction: function (data) {
if (data.modal || data.parentId == this.pageId) {
let pageId = data.pageId;
let type = data.type;
let modal = data.modal
if (!modal)
modal = this.viewPort.modals.get(pageId);
if (modal) {
switch (type) {
case 'open':
if (data.parentId == this.pageId)
this.viewPort._createModal(data)
break;
case 'close':
modal.viewPort._removeModal(modal)
break;
case 'minMax':
modal.el.position.minMax();
break;
case 'park':
modal.togglePark();
break;
}
document.dispatchEvent(new CustomEvent(`${type}Modal`, {
detail: {}
}))
}
}
}
}
export default new CoCreateModal();