silex-website-builder-goodevent
Version:
Free and easy website builder for everyone.
253 lines (226 loc) • 8.6 kB
text/typescript
import { getUiElements } from '../view/UiElements';
/**
* Silex, live web creation
* http://projects.silexlabs.org/?/silex/
*
* Copyright (c) 2012 Silex Labs
* http://www.silexlabs.org/
*
* Silex is available under the GPL license
* http://www.silexlabs.org/silex/silex-licensing/
*/
interface Dialog {
set(optoins: any);
close();
destroy();
setContent(el: HTMLElement|DocumentFragment);
}
interface Options {
labelOk?: string;
labelCancel?: string;
defaultValue?: string;
cancel?: () => {};
title: string;
content: string;
placeholder?: string;
}
/**
* @fileoverview Helper class for common tasks
*
*/
export class SilexNotification {
static get isActive(): boolean {
return !!SilexNotification.currentDialog && !document.querySelector('.alerts').classList.contains('closed');
}
/**
* flag to indicate wether a modal dialog is opened
*/
private static get currentDialog(): HTMLElement {
return document.querySelector(`.${SilexNotification.NOTIFICATION_CSS_CLASS}`);
}
/**
* close (cancel) the current notification
*/
static close(isOk= false) {
if (SilexNotification.currentDialog) {
// hide dialogs
const container: HTMLElement = document.querySelector('.alerts');
container.classList.add('closed');
// cleanup
const cbk = isOk ? SilexNotification.cbkOk : SilexNotification.cbkCancel;
SilexNotification.currentDialog.remove();
SilexNotification.cbkCancel = null;
SilexNotification.cbkOk = null;
// all done, we can open another one or do something
cbk();
}
}
/**
* display a message
*/
static alert(title: string, content: string, ok: () => any, labelOk: string = 'ok') {
SilexNotification.close();
SilexNotification.create(SilexNotification.getMarkup({
labelOk,
title,
content,
}));
SilexNotification.cbkCancel = SilexNotification.cbkOk = () => ok();
(SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_ok`) as HTMLElement).onclick = (e) => SilexNotification.close();
}
/**
* ask for a text
*/
static prompt(title: string, content: string, defaultValue: string, placeholder: string, cbk: (isOk: boolean, value: string) => any, labelOk: string = 'ok', labelCancel: string = 'cancel') {
SilexNotification.close();
SilexNotification.create(SilexNotification.getMarkup({
labelOk,
labelCancel,
defaultValue,
title,
content,
placeholder,
}));
const input: HTMLInputElement = SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_value`);
SilexNotification.cbkOk = () => {
cbk(true, input.value);
};
SilexNotification.cbkCancel = () => {
cbk(false, null);
};
(SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_ok`) as HTMLElement).onclick = (e) => SilexNotification.close(true);
(SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_cancel`) as HTMLElement).onclick = (e) => SilexNotification.close(false);
}
/**
* ask for confirmation
*/
static confirm(title: string, content: string, cbk: (isOk: boolean) => any, labelOk: string = 'ok', labelCancel: string = 'cancel') {
SilexNotification.close();
SilexNotification.create(SilexNotification.getMarkup({
labelOk,
labelCancel,
title,
content,
}));
SilexNotification.cbkOk = () => cbk(true);
SilexNotification.cbkCancel = () => cbk(false);
(SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_ok`) as HTMLElement).onclick = (e) => SilexNotification.close(true);
(SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_cancel`) as HTMLElement).onclick = (e) => SilexNotification.close(false);
}
/**
* notify the user with success formatting
*/
static notifySuccess(message: string) {
const container: HTMLElement = document.querySelector('.alerts-notify');
const el = document.createElement('p');
el.innerHTML = message;
container.appendChild(el);
const id = setTimeout(() => {
el.remove();
}, SilexNotification.NOTIFICATION_DURATION_MS);
el.onclick = (e) => {
clearTimeout(id);
el.remove();
};
}
/**
* notify the user with success formatting
*/
static notifyError(message: string) {
console.error(message);
SilexNotification.notifySuccess(message);
}
/**
* change the text of the current notification
*/
static setContent(el: HTMLElement|DocumentFragment, keepExisiting= false) {
if (SilexNotification.currentDialog) {
const container = SilexNotification.currentDialog.querySelector(`.${SilexNotification.NOTIFICATION_CSS_CLASS}_content`);
if (!keepExisiting) { container.innerHTML = ''; }
container.appendChild(el);
}
}
/**
* change the text of the current notification
*/
static setText(text: string) {
if (SilexNotification.currentDialog) {
const el = document.createElement('div');
el.insertAdjacentHTML('afterbegin', `<p>${text}</p>`);
SilexNotification.setContent(el);
}
}
/**
* add a button to the button bar
*/
static addButton(el: HTMLElement|DocumentFragment) {
if (SilexNotification.currentDialog) {
SilexNotification.currentDialog.querySelector(`.${SilexNotification.NOTIFICATION_CSS_CLASS}_buttons`);
}
}
/**
* add an HTML panel with info of type "while you wait, here is an info"
*/
static setInfoPanel(element: HTMLElement) {
if (SilexNotification.currentDialog) {
let infoPanel = SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_info`) as HTMLElement;
if (!infoPanel) {
infoPanel = document.createElement('div');
infoPanel.insertAdjacentHTML('afterbegin', `<p class="${SilexNotification.NOTIFICATION_CSS_CLASS}_info"></p>`);
SilexNotification.setContent(infoPanel, true);
}
// limit height so that small screens still see the close button
const stage = getUiElements().stage.querySelector('iframe');
infoPanel.style.maxHeight = Math.round(stage.clientHeight * 2 / 3) + 'px';
SilexNotification.currentDialog.insertBefore(infoPanel, SilexNotification.currentDialog.childNodes[SilexNotification.currentDialog.childNodes.length - 1]);
infoPanel.innerHTML = '';
infoPanel.appendChild(element);
}
}
private static NOTIFICATION_DURATION_MS = 30000;
private static NOTIFICATION_CSS_CLASS = 'notification-dialog';
private static cbkOk: () => void;
private static cbkCancel: () => void;
private static getMarkup(options: Options) {
return `
<section class="${SilexNotification.NOTIFICATION_CSS_CLASS}">
<h2>${options.title}</h2>
<p class="${SilexNotification.NOTIFICATION_CSS_CLASS}_content">
${options.content}
${
typeof options.defaultValue !== 'undefined' ? `
<input
id="${SilexNotification.NOTIFICATION_CSS_CLASS}_value"
${options.placeholder ? `placeholder="${options.placeholder}"` : ''}
class="block-dialog" type="text" value="${options.defaultValue}"
>`
: ''
}
</p>
<div class="${SilexNotification.NOTIFICATION_CSS_CLASS}_buttons">
${options.labelCancel ? `<input id="${SilexNotification.NOTIFICATION_CSS_CLASS}_cancel" type="button" value="${options.labelCancel}">` : ''}
${options.labelOk ? `<input id="${SilexNotification.NOTIFICATION_CSS_CLASS}_ok" type="button" value="${options.labelOk}">` : ''}
</div>
</section>
`;
}
private static create(markup: string) {
const container: HTMLElement = document.querySelector('.alerts');
container.insertAdjacentHTML('afterbegin', markup);
container.classList.remove('closed');
const input = (SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_value`) as HTMLElement);
if (input) {
input.focus();
}
}
constructor() {
throw new Error('this is a static class and it canot be instanciated');
}
}
// else {
// Notifications are not supported or denied
// }
// Desktop notifications disabled because it disturbs more than it serves
// FIXME: remove all calls to nativeNotification since it is not useful anymore
// Notification.activateNative();
// :facepalm: