[BUGFIX] Prevent loading jsfunc.inline.js twice
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Resources / Private / TypeScript / Notification.ts
1 /*
2  * This file is part of the TYPO3 CMS project.
3  *
4  * It is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU General Public License, either version 2
6  * of the License, or any later version.
7  *
8  * For the full copyright and license information, please read the
9  * LICENSE.txt file that was distributed with this source code.
10  *
11  * The TYPO3 project - inspiring people to share!
12  */
13
14 import {SeverityEnum} from './Enum/Severity';
15 import Severity = require('./Severity');
16
17 /**
18  * Module: TYPO3/CMS/Backend/Notification
19  * Notification API for the TYPO3 backend
20  */
21 class Notification {
22   private static duration: number = 5;
23   private static messageContainer: JQuery = null;
24
25   /**
26    * Show a notice notification
27    *
28    * @param {string} title
29    * @param {string} message
30    * @param {number} duration
31    */
32   public static notice(title: string, message: string, duration: number): void {
33     Notification.showMessage(title, message, SeverityEnum.notice, duration);
34   }
35
36   /**
37    * Show a info notification
38    *
39    * @param {string} title
40    * @param {string} message
41    * @param {number} duration
42    */
43   public static info(title: string, message: string, duration: number): void {
44     Notification.showMessage(title, message, SeverityEnum.info, duration);
45   }
46
47   /**
48    * Show a success notification
49    *
50    * @param {string} title
51    * @param {string} message
52    * @param {number} duration
53    */
54   public static success(title: string, message: string, duration: number): void {
55     Notification.showMessage(title, message, SeverityEnum.ok, duration);
56   }
57
58   /**
59    * Show a warning notification
60    *
61    * @param {string} title
62    * @param {string} message
63    * @param {number} duration
64    */
65   public static warning(title: string, message: string, duration: number): void {
66     Notification.showMessage(title, message, SeverityEnum.warning, duration);
67   }
68
69   /**
70    * Show a error notification
71    *
72    * @param {string} title
73    * @param {string} message
74    * @param {number} duration
75    */
76   public static error(title: string, message: string, duration: number = 0): void {
77     Notification.showMessage(title, message, SeverityEnum.error, duration);
78   }
79
80   /**
81    * @param {string} title
82    * @param {string} message
83    * @param {SeverityEnum} severity
84    * @param {number} duration
85    */
86   public static showMessage(title: string,
87                             message: string,
88                             severity: SeverityEnum,
89                             duration: number | string = this.duration): void {
90     const className = Severity.getCssClass(severity);
91     let icon = '';
92     switch (severity) {
93       case SeverityEnum.notice:
94         icon = 'lightbulb-o';
95         break;
96       case SeverityEnum.ok:
97         icon = 'check';
98         break;
99       case SeverityEnum.warning:
100         icon = 'exclamation';
101         break;
102       case SeverityEnum.error:
103         icon = 'times';
104         break;
105       case SeverityEnum.info:
106       default:
107         icon = 'info';
108     }
109
110     duration = (typeof duration === 'undefined')
111       ? this.duration
112       : (
113         typeof duration === 'string'
114           ? parseFloat(duration)
115           : duration
116       );
117
118     if (this.messageContainer === null) {
119       this.messageContainer = $('<div id="alert-container"></div>').appendTo('body');
120     }
121     const $box = $(
122       '<div class="alert alert-' + className + ' alert-dismissible fade" role="alert">' +
123       '<button type="button" class="close" data-dismiss="alert">' +
124       '<span aria-hidden="true"><i class="fa fa-times-circle"></i></span>' +
125       '<span class="sr-only">Close</span>' +
126       '</button>' +
127       '<div class="media">' +
128       '<div class="media-left">' +
129       '<span class="fa-stack fa-lg">' +
130       '<i class="fa fa-circle fa-stack-2x"></i>' +
131       '<i class="fa fa-' + icon + ' fa-stack-1x"></i>' +
132       '</span>' +
133       '</div>' +
134       '<div class="media-body">' +
135       '<h4 class="alert-title"></h4>' +
136       '<p class="alert-message text-pre-wrap"></p>' +
137       '</div>' +
138       '</div>' +
139       '</div>'
140     );
141     $box.find('.alert-title').text(title);
142     $box.find('.alert-message').text(message);
143     $box.on('close.bs.alert', (e: Event) => {
144       e.preventDefault();
145       const $me = $(e.currentTarget);
146       $me
147         .clearQueue()
148         .queue((next: any): void => {
149           $me.removeClass('in');
150           next();
151         })
152         .slideUp(() => {
153           $me.remove();
154         });
155     });
156     $box.appendTo(this.messageContainer);
157     $box.delay(200)
158       .queue((next: any): void => {
159         $box.addClass('in');
160         next();
161       });
162
163     if (duration > 0) {
164       // if duration > 0 dismiss alert
165       $box.delay(duration * 1000)
166         .queue((next: any): void => {
167           $box.alert('close');
168           next();
169         });
170     }
171   }
172 }
173
174 let notificationObject;
175
176 try {
177   // fetch from parent
178   if (parent && parent.window.TYPO3 && parent.window.TYPO3.Notification) {
179     notificationObject = parent.window.TYPO3.Notification;
180   }
181
182   // fetch object from outer frame
183   if (top && top.TYPO3.Notification) {
184     notificationObject = top.TYPO3.Notification;
185   }
186 } catch (e) {
187   // This only happens if the opener, parent or top is some other url (eg a local file)
188   // which loaded the current window. Then the browser's cross domain policy jumps in
189   // and raises an exception.
190   // For this case we are safe and we can create our global object below.
191 }
192
193 if (!notificationObject) {
194   notificationObject = Notification;
195
196   // attach to global frame
197   if (typeof TYPO3 !== 'undefined') {
198     TYPO3.Notification = notificationObject;
199   }
200 }
201 export = notificationObject;