106 lines
2.9 KiB
JavaScript
106 lines
2.9 KiB
JavaScript
const objToDom=obj => {
|
|
if(obj instanceof Node) {
|
|
return obj;
|
|
} else if(obj[Popup.EM]) {
|
|
let em=document.createElement('em');
|
|
em.appendChild(document.createTextNode(obj[Popup.EM]));
|
|
return em;
|
|
} else if(obj[Popup.STRONG]) {
|
|
let em=document.createElement('strong');
|
|
em.appendChild(document.createTextNode(obj[Popup.STRONG]));
|
|
return em;
|
|
} else if(typeof obj=='string' || typeof obj=='number') {
|
|
return document.createTextNode(obj+'');
|
|
} else if(Array.isArray(obj)) {
|
|
let ul=document.createElement('ul');
|
|
obj.forEach(elem => ul.appendChild(objToDom(elem)));
|
|
return ul;
|
|
} else {
|
|
let table=document.createElement('table');
|
|
Object
|
|
.keys(obj)
|
|
.forEach(key => {
|
|
let tr=table.appendChild(document.createElement('tr'));
|
|
tr.appendChild(document.createElement('th')).appendChild(document.createTextNode(key));
|
|
tr.appendChild(document.createElement('td')).appendChild(objToDom(obj[key]));
|
|
});
|
|
return table;
|
|
}
|
|
}
|
|
|
|
class Popup {
|
|
constructor(title, content=[], buttons={}, large=false) {
|
|
this.title=title;
|
|
this.content=content.map(objToDom);
|
|
this.buttons={...buttons};
|
|
this.large=large;
|
|
}
|
|
|
|
addContent(cnt) {
|
|
this.content.push(objToDom(cnt));
|
|
}
|
|
addText(cnt) {
|
|
this.content.push(document.createTextNode(cnt));
|
|
}
|
|
addEm(cnt) {
|
|
this.content.push(objToDom({[Popup.EM]: cnt}));
|
|
}
|
|
addStrong(cnt) {
|
|
this.content.push(objToDom({[Popup.STRONG]: cnt}));
|
|
}
|
|
addHeading(cnt, level=2) {
|
|
let hn=document.createElement('h'+level);
|
|
hn.innerText=cnt;
|
|
this.content.push(hn);
|
|
}
|
|
|
|
async display(parent=document.body) {
|
|
let outer=document.createElement('div');
|
|
outer.classList.add('popup');
|
|
let popup=outer.appendChild(document.createElement('div'));
|
|
popup.classList.add('content');
|
|
if(this.large) popup.classList.add('large');
|
|
|
|
let title=popup.appendChild(document.createElement('h1'));
|
|
title.innerText=this.title;
|
|
|
|
let contentSection=popup.appendChild(document.createElement('section'));
|
|
this.content.forEach(elem => contentSection.appendChild(elem));
|
|
|
|
let buttonSection=popup.appendChild(document.createElement('section'));
|
|
let buttons=Object.keys(this.buttons).map(btn => {
|
|
let button=document.createElement('button');
|
|
button.innerText=this.buttons[btn];
|
|
button.dataset.code=btn;
|
|
return button;
|
|
});
|
|
buttons.forEach(btn => buttonSection.appendChild(btn));
|
|
|
|
parent.appendChild(outer);
|
|
Popup.displayed.push(this);
|
|
|
|
const btnActions=buttons.map(btn => new Promise(ok => {
|
|
btn.addEventListener('click', e => {
|
|
e.preventDefault();
|
|
return ok(btn.dataset.code);
|
|
});
|
|
}));
|
|
const dismissAction=new Promise(ok => this.dismiss=ok);
|
|
|
|
const code=await Promise.race(btnActions.concat([dismissAction]));
|
|
|
|
parent.removeChild(outer);
|
|
Popup.displayed.splice(Popup.displayed.indexOf(this), 1);
|
|
return code;
|
|
}
|
|
}
|
|
|
|
Popup.EM=Symbol('EM');
|
|
Popup.STRONG=Symbol('STRONG');
|
|
|
|
Popup.displayed=[];
|
|
Popup.dismiss=arg => {
|
|
Popup.displayed.forEach(p => p.dismiss(arg));
|
|
};
|
|
|
|
return module.exports=Popup;
|