65 lines
2.0 KiB
JavaScript
65 lines
2.0 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
function messageBox({title, contents, buttons, onclick}) {
|
||
|
// keep the same reference to be able to remove the listener later
|
||
|
messageBox.close = messageBox.close || close;
|
||
|
if (messageBox.element) {
|
||
|
messageBox.element.remove();
|
||
|
}
|
||
|
const id = 'message-box';
|
||
|
const putAs = typeof contents == 'string' ? 'innerHTML' : 'appendChild';
|
||
|
messageBox.element = $element({id, appendChild: [
|
||
|
$element({id: `${id}-title`, innerHTML: title}),
|
||
|
$element({id: `${id}-close-icon`, onclick: messageBox.close}),
|
||
|
$element({id: `${id}-contents`, [putAs]: contents}),
|
||
|
$element({id: `${id}-buttons`,
|
||
|
onclick: relayButtonClick,
|
||
|
appendChild: (buttons || []).map(textContent =>
|
||
|
textContent && $element({tag: 'button', textContent}))
|
||
|
}),
|
||
|
]});
|
||
|
show();
|
||
|
return messageBox.element;
|
||
|
|
||
|
function show() {
|
||
|
document.body.appendChild(messageBox.element);
|
||
|
document.addEventListener('keydown', messageBox.close);
|
||
|
}
|
||
|
|
||
|
function close(event) {
|
||
|
if ((!event
|
||
|
|| event.type == 'click'
|
||
|
|| event.keyCode == 27 && !event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey)
|
||
|
&& messageBox.element) {
|
||
|
const box = messageBox.element;
|
||
|
box.classList.add('fadeout');
|
||
|
box.addEventListener('animationend', function _() {
|
||
|
box.removeEventListener('animationend', _);
|
||
|
box.remove();
|
||
|
});
|
||
|
document.removeEventListener('keydown', messageBox.close);
|
||
|
$(`#${id}-buttons`).onclick = null;
|
||
|
messageBox.element = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function relayButtonClick(event) {
|
||
|
const button = event.target.closest('button');
|
||
|
if (button) {
|
||
|
close();
|
||
|
if (onclick) {
|
||
|
onclick([...this.children].indexOf(button));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function $element(opt) {
|
||
|
const element = document.createElement(opt.tag || 'div');
|
||
|
(opt.appendChild instanceof Array ? opt.appendChild : [opt.appendChild])
|
||
|
.forEach(child => child && element.appendChild(child));
|
||
|
delete opt.appendChild;
|
||
|
delete opt.tag;
|
||
|
return Object.assign(element, opt);
|
||
|
}
|
||
|
}
|