- "use strict";
- /**
- * Defines a dialog-panel to display messages.
- * Every message that fulfills will get the dialog-content as well as the pressed button as return.
- *
- *
- * <i>Copyright (c) 2014 ITSA - https://github.com/itsa</i>
- * New BSD License - http://choosealicense.com/licenses/bsd-3-clause/
- *
- *
- * @module dialog
- * @class Dialog
- * @since 0.0.1
- */
-
- require('js-ext');
- require('polyfill');
- require('./css/dialog.css');
-
- var NAME = '[dialog]: ',
- MESSAGE_LEVELS = {
- 'message': 1,
- 'warn': 2,
- 'error': 3
- },
- MESSAGE_HASHES = {
- 'message': 'messages',
- 'warn': 'warnings',
- 'error': 'errors'
- },
- MESSAGE_HASHES_NR = {
- 1: 'messages',
- 2: 'warnings',
- 3: 'errors'
- },
- FOLLOWUP_DELAY = 150,
- createHashMap = require('js-ext/extra/hashmap.js').createMap;
-
- module.exports = function (window) {
-
- var DOCUMENT = window.document,
- Classes = require('js-ext/extra/classes.js'),
- UTILS = require('utils'),
- later = UTILS.later,
- async = UTILS.async,
- dialog, Dialog, Event;
-
- window._ITSAmodules || Object.protectedProp(window, '_ITSAmodules', createHashMap());
-
- /*jshint boss:true */
- if (Dialog=window._ITSAmodules.Dialog) {
- /*jshint boss:false */
- return Dialog; // Dialog was already created
- }
-
- require('panel')(window);
- Event = require('itsa-event');
-
- /**
- * Model that is passed through to the Panel.
- *
- * @property model
- * @default {
- draggable: true
- }
- * @type Object
- * @since 0.0.1
- */
-
- /**
- * Internal property that tells what message-level is currently active.
- *
- * @property _currentMessageLevel
- * @default 0
- * @type Number
- * @private
- * @since 0.0.1
- */
-
- /**
- * Internal hash all queued message with level=1 (*:message)
- *
- * @property messages
- * @default []
- * @type Array
- * @since 0.0.1
- */
-
- /**
- * Internal hash all queued message with level=2 (*:warn)
- *
- * @property warnings
- * @default []
- * @type Array
- * @since 0.0.1
- */
-
- /**
- * Internal hash all queued message with level=3 (*:error)
- *
- * @property errors
- * @default []
- * @type Array
- * @since 0.0.1
- */
- Dialog = Classes.createClass(function() {
- var instance = this;
- instance.model = {
- draggable: true
- };
- instance._currentMessageLevel = 0;
- instance.messages = [];
- instance.warnings = [];
- instance.errors = [];
- instance.createContainer();
- instance.setupListeners();
- }, {
-
- /**
- * Creates a Panel-instance that will be used to display the messages.
- * Sets instance.model as panel's model and defines model.callback
- * which fulfills the message when a button on the dialog is pressed,
- *
- * @method createContainer
- * @since 0.0.1
- */
- createContainer: function() {
- var instance = this,
- model = instance.model;
- model.callback = function(buttonNode) {
- var containerNode = DOCUMENT.createElement('div'),
- contentNode = instance.panel.getElement('>div[is="content"]'),
- messagePromise = model.messagePromise;
- containerNode = contentNode.cloneNode(true);
- // now append a copy of the buttonNode:
- containerNode.append(buttonNode.getOuterHTML());
- messagePromise.fulfill(containerNode);
- // we can safely remove the newly created container-node: the vdom holds it for 1 minute
- containerNode.remove();
- };
- instance.panel = DOCUMENT.createPanel(model);
- },
-
- /**
- * Processes messages that are emitted by `messages`-module and add them in the queue.
- *
- * @method queueMessage
- * @param e {Object} the eventobject
- * @since 0.0.1
- */
- queueMessage: function(e) {
- var instance = this,
- messagePromise = e.messagePromise,
- type = e.type,
- level = MESSAGE_LEVELS[type],
- list = instance[MESSAGE_HASHES[type]];
- list[list.length] = messagePromise;
- messagePromise.finally(
- function() {
- list.remove(messagePromise);
- // handle the next message (if there)
- instance.handleMessage(true);
- }
- );
- (level>instance._currentMessageLevel) && instance.handleMessage(!instance.isWaiting(), level);
- },
-
- /**
- * Defines subscribers to the events: *:message, *:warn and *:error.
- *
- * @method setupListeners
- * @since 0.0.1
- */
- setupListeners: function() {
- var instance = this;
- Event.after(['*:message', '*:warn', '*:error'], instance.queueMessage.bind(instance));
- },
-
- /**
- * Tells whether `dialog` is waitin g for new messages and is currently iddle.
- *
- * @method isWaiting
- * @return {Boolean} whether `dialog` is waitin g for new messages
- * @since 0.0.1
- */
- isWaiting: function() {
- return (this._currentMessageLevel===0);
- },
-
- /**
- * Retrieves the next message from the queue and calls showMessage() if it finds one.
- *
- * @method handleMessage
- * @param [delay] {Boolean} if there should be a delay between the previous dialog and the new one
- * @param [level] {Number} to force handling a specific level
- * @since 0.0.1
- */
- handleMessage: function(delay, level) {
- var instance = this,
- model = instance.model,
- messagePromise;
- if (!level) {
- // search level
- if (instance.errors.length>0) {
- level = 3;
- }
- else if (instance.warnings.length>0) {
- level = 2;
- }
- else if (instance.messages.length>0) {
- level = 1;
- }
- }
- if (!level || (instance[MESSAGE_HASHES_NR[level]].length===0)) {
- // DO NOT make messagePromise null: it sould be there as return value
- // of the last message
- instance._currentMessageLevel = 0;
- model.header = null;
- model.content = '';
- model.footer = null;
- model.validate = null;
- model.visible = false;
- return;
- }
- instance._currentMessageLevel = level;
- // now process the highest message
- messagePromise = instance[MESSAGE_HASHES_NR[level]][0];
- if (delay) {
- model.visible = false;
- later(instance.showMessage.bind(instance, messagePromise), FOLLOWUP_DELAY);
- }
- else {
- async(instance.showMessage.bind(instance, messagePromise));
- }
- },
-
- /**
- * Shows the specified message-promise.
- *
- * @method showMessage
- * @param messagePromise {Promise} the message to be shown.
- * @since 0.0.1
- */
- showMessage: function(messagePromise) {
- var model = this.model;
- window.scrollTo(0, 0);
- model.messagePromise = messagePromise;
- model.header = messagePromise.header;
- model.content = messagePromise.content;
- model.footer = messagePromise.footer;
- model.validate = messagePromise.validate;
- model.visible = true;
- }
- });
-
- // instantiate Dialog and make it operational:
- dialog = new Dialog();
-
- window._ITSAmodules.Dialog = Dialog;
-
- return Dialog;
- };
-