MDL-35959 Correct footer for M.core.dialogue
[moodle.git] / enrol / yui / notification / notification.js
CommitLineData
6db3eee0
SH
1YUI.add('moodle-enrol-notification', function(Y) {
2
3var DIALOGUE_NAME = 'Moodle dialogue',
4 DIALOGUE_PREFIX = 'moodle-dialogue',
5 CONFIRM_NAME = 'Moodle confirmation dialogue',
6 EXCEPTION_NAME = 'Moodle exception',
7 AJAXEXCEPTION_NAME = 'Moodle AJAX exception',
8 ALERT_NAME = 'Moodle alert',
9 C = Y.Node.create,
10 BASE = 'notificationBase',
11 LIGHTBOX = 'lightbox',
12 NODELIGHTBOX = 'nodeLightbox',
13 COUNT = 0,
14 CONFIRMYES = 'yesLabel',
15 CONFIRMNO = 'noLabel',
16 TITLE = 'title',
17 QUESTION = 'question',
18 CSS = {
19 BASE : 'moodle-dialogue-base',
20 WRAP : 'moodle-dialogue-wrap',
21 HEADER : 'moodle-dialogue-hd',
22 BODY : 'moodle-dialogue-bd',
23 CONTENT : 'moodle-dialogue-content',
272dfda3 24 FOOTER : 'moodle-dialogue-ft',
6db3eee0
SH
25 HIDDEN : 'hidden',
26 LIGHTBOX : 'moodle-dialogue-lightbox'
27 };
28
29var DIALOGUE = function(config) {
30 COUNT++;
31 var id = 'moodle-dialogue-'+COUNT;
32 config.notificationBase =
33 C('<div class="'+CSS.BASE+'">')
34 .append(C('<div class="'+CSS.LIGHTBOX+' '+CSS.HIDDEN+'"></div>'))
35 .append(C('<div id="'+id+'" class="'+CSS.WRAP+'"></div>')
36 .append(C('<div class="'+CSS.HEADER+' yui3-widget-hd"></div>'))
37 .append(C('<div class="'+CSS.BODY+' yui3-widget-bd"></div>'))
272dfda3 38 .append(C('<div class="'+CSS.FOOTER+' yui3-widget-ft"></div>')));
6db3eee0
SH
39 Y.one(document.body).append(config.notificationBase);
40 config.srcNode = '#'+id;
41 config.width = config.width || '400px';
42 config.visible = config.visible || false;
43 config.center = config.centered || true;
44 config.centered = false;
45 DIALOGUE.superclass.constructor.apply(this, [config]);
8505d925 46};
6db3eee0
SH
47Y.extend(DIALOGUE, Y.Overlay, {
48 initializer : function(config) {
49 this.set(NODELIGHTBOX, this.get(BASE).one('.'+CSS.LIGHTBOX).setStyle('opacity', 0.5));
50 this.after('visibleChange', this.visibilityChanged, this);
51 this.after('headerContentChange', function(e){
52 var h = (this.get('closeButton'))?this.get(BASE).one('.'+CSS.HEADER):false;
53 if (h && !h.one('.closebutton')) {
54 var c = C('<div class="closebutton"></div>');
55 c.on('click', this.hide, this);
56 h.append(c);
57 }
58 }, this);
59 this.render();
60 this.show();
61 },
62 visibilityChanged : function(e) {
63 switch (e.attrName) {
64 case 'visible':
65 if (this.get(LIGHTBOX)) {
66 var l = this.get(NODELIGHTBOX);
67 if (!e.prevVal && e.newVal) {
68 l.setStyle('height',l.get('docHeight')+'px').removeClass(CSS.HIDDEN);
69 } else if (e.prevVal && !e.newVal) {
70 l.addClass(CSS.HIDDEN);
71 }
72 }
73 if (this.get('center') && !e.prevVal && e.newVal) {
74 this.centerDialogue();
75 }
06a78ea6 76 if (this.get('draggable')) {
984ec46e
ARN
77 var titlebar = '#' + this.get('id') + ' .' + CSS.HEADER;
78 this.plug(Y.Plugin.Drag, {handles : [titlebar]});
346099f0 79 this.dd.addInvalid('div.closebutton');
984ec46e 80 Y.one(titlebar).setStyle('cursor', 'move');
06a78ea6 81 }
6db3eee0
SH
82 break;
83 }
84 },
85 centerDialogue : function() {
86 var bb = this.get('boundingBox'), hidden = bb.hasClass(DIALOGUE_PREFIX+'-hidden');
87 if (hidden) {
88 bb.setStyle('top', '-1000px').removeClass(DIALOGUE_PREFIX+'-hidden');
89 }
bc6b1799
ARN
90 var x = Math.max(Math.round((bb.get('winWidth') - bb.get('offsetWidth'))/2), 15);
91 var y = Math.max(Math.round((bb.get('winHeight') - bb.get('offsetHeight'))/2), 15) + Y.one(window).get('scrollTop');
92
6db3eee0
SH
93 if (hidden) {
94 bb.addClass(DIALOGUE_PREFIX+'-hidden');
95 }
96 bb.setStyle('left', x).setStyle('top', y);
97 }
98}, {
99 NAME : DIALOGUE_NAME,
100 CSS_PREFIX : DIALOGUE_PREFIX,
101 ATTRS : {
102 notificationBase : {
103
104 },
105 nodeLightbox : {
106 value : null
107 },
108 lightbox : {
109 validator : Y.Lang.isBoolean,
110 value : true
111 },
112 closeButton : {
113 validator : Y.Lang.isBoolean,
114 value : true
115 },
116 center : {
117 validator : Y.Lang.isBoolean,
118 value : true
06a78ea6
ARN
119 },
120 draggable : {
121 validator : Y.Lang.isBoolean,
122 value : false
6db3eee0
SH
123 }
124 }
125});
126
127var ALERT = function(config) {
128 config.closeButton = false;
129 ALERT.superclass.constructor.apply(this, [config]);
8505d925 130};
6db3eee0
SH
131Y.extend(ALERT, DIALOGUE, {
132 _enterKeypress : null,
133 initializer : function(config) {
134 this.publish('complete');
135 var yes = C('<input type="button" value="'+this.get(CONFIRMYES)+'" />'),
136 content = C('<div class="confirmation-dialogue"></div>')
137 .append(C('<div class="confirmation-message">'+this.get('message')+'</div>'))
138 .append(C('<div class="confirmation-buttons"></div>')
139 .append(yes));
140 this.get(BASE).addClass('moodle-dialogue-confirm');
141 this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
142 this.setStdModContent(Y.WidgetStdMod.HEADER, this.get(TITLE), Y.WidgetStdMod.REPLACE);
143 this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
144 this._enterKeypress = Y.on('key', this.submit, window, 'down:13', this);
145 yes.on('click', this.submit, this);
8505d925 146 },
6db3eee0
SH
147 submit : function(e, outcome) {
148 this._enterKeypress.detach();
149 this.fire('complete');
150 this.hide();
151 this.destroy();
152 }
153}, {
154 NAME : ALERT_NAME,
155 CSS_PREFIX : DIALOGUE_PREFIX,
156 ATTRS : {
157 title : {
158 validator : Y.Lang.isString,
159 value : 'Alert'
160 },
161 message : {
162 validator : Y.Lang.isString,
163 value : 'Confirm'
164 },
165 yesLabel : {
166 validator : Y.Lang.isString,
167 setter : function(txt) {
168 if (!txt) {
169 txt = 'Ok';
170 }
171 return txt;
172 },
173 value : 'Ok'
174 }
175 }
176});
177
178var CONFIRM = function(config) {
179 CONFIRM.superclass.constructor.apply(this, [config]);
8505d925 180};
6db3eee0
SH
181Y.extend(CONFIRM, DIALOGUE, {
182 _enterKeypress : null,
183 _escKeypress : null,
184 initializer : function(config) {
185 this.publish('complete');
186 this.publish('complete-yes');
187 this.publish('complete-no');
188 var yes = C('<input type="button" value="'+this.get(CONFIRMYES)+'" />'),
189 no = C('<input type="button" value="'+this.get(CONFIRMNO)+'" />'),
190 content = C('<div class="confirmation-dialogue"></div>')
191 .append(C('<div class="confirmation-message">'+this.get(QUESTION)+'</div>'))
192 .append(C('<div class="confirmation-buttons"></div>')
193 .append(yes)
194 .append(no));
195 this.get(BASE).addClass('moodle-dialogue-confirm');
196 this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
197 this.setStdModContent(Y.WidgetStdMod.HEADER, this.get(TITLE), Y.WidgetStdMod.REPLACE);
198 this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
199 this._enterKeypress = Y.on('key', this.submit, window, 'down:13', this, true);
200 this._escKeypress = Y.on('key', this.submit, window, 'down:27', this, false);
201 yes.on('click', this.submit, this, true);
202 no.on('click', this.submit, this, false);
203 },
204 submit : function(e, outcome) {
205 this._enterKeypress.detach();
206 this._escKeypress.detach();
207 this.fire('complete', outcome);
208 if (outcome) {
209 this.fire('complete-yes');
210 } else {
211 this.fire('complete-no');
212 }
213 this.hide();
214 this.destroy();
215 }
216}, {
217 NAME : CONFIRM_NAME,
218 CSS_PREFIX : DIALOGUE_PREFIX,
219 ATTRS : {
220 yesLabel : {
221 validator : Y.Lang.isString,
222 value : 'Yes'
223 },
224 noLabel : {
225 validator : Y.Lang.isString,
226 value : 'No'
227 },
228 title : {
229 validator : Y.Lang.isString,
230 value : 'Confirm'
231 },
232 question : {
233 validator : Y.Lang.isString,
234 value : 'Are you sure?'
235 }
236 }
237});
238Y.augment(CONFIRM, Y.EventTarget);
239
240var EXCEPTION = function(config) {
241 config.width = config.width || (M.cfg.developerdebug)?Math.floor(Y.one(document.body).get('winWidth')/3)+'px':null;
242 config.closeButton = true;
243 EXCEPTION.superclass.constructor.apply(this, [config]);
8505d925 244};
6db3eee0
SH
245Y.extend(EXCEPTION, DIALOGUE, {
246 _hideTimeout : null,
247 _keypress : null,
248 initializer : function(config) {
249 this.get(BASE).addClass('moodle-dialogue-exception');
250 this.setStdModContent(Y.WidgetStdMod.HEADER, config.name, Y.WidgetStdMod.REPLACE);
251 var content = C('<div class="moodle-exception"></div>')
252 .append(C('<div class="moodle-exception-message">'+this.get('message')+'</div>'))
253 .append(C('<div class="moodle-exception-param hidden param-filename"><label>File:</label> '+this.get('fileName')+'</div>'))
254 .append(C('<div class="moodle-exception-param hidden param-linenumber"><label>Line:</label> '+this.get('lineNumber')+'</div>'))
255 .append(C('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>'+this.get('stack')+'</pre></div>'));
256 if (M.cfg.developerdebug) {
257 content.all('.moodle-exception-param').removeClass('hidden');
258 }
259 this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
260
261 var self = this;
262 var delay = this.get('hideTimeoutDelay');
263 if (delay) {
264 this._hideTimeout = setTimeout(function(){self.hide();}, delay);
265 }
266 this.after('visibleChange', this.visibilityChanged, this);
267 this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
268 this._keypress = Y.on('key', this.hide, window, 'down:13,27', this);
269 this.centerDialogue();
270 },
271 visibilityChanged : function(e) {
272 if (e.attrName == 'visible' && e.prevVal && !e.newVal) {
273 if (this._keypress) this._keypress.detach();
274 var self = this;
275 setTimeout(function(){self.destroy();}, 1000);
276 }
277 }
278}, {
279 NAME : EXCEPTION_NAME,
280 CSS_PREFIX : DIALOGUE_PREFIX,
281 ATTRS : {
282 message : {
283 value : ''
284 },
285 name : {
286 value : ''
287 },
288 fileName : {
289 value : ''
290 },
291 lineNumber : {
292 value : ''
293 },
294 stack : {
295 setter : function(str) {
296 var lines = str.split("\n");
297 var pattern = new RegExp('^(.+)@('+M.cfg.wwwroot+')?(.{0,75}).*:(\\d+)$');
298 for (var i in lines) {
299 lines[i] = lines[i].replace(pattern, "<div class='stacktrace-line'>ln: $4</div><div class='stacktrace-file'>$3</div><div class='stacktrace-call'>$1</div>");
300 }
301 return lines.join('');
302 },
303 value : ''
304 },
305 hideTimeoutDelay : {
306 validator : Y.Lang.isNumber,
307 value : null
308 }
309 }
310});
311
312var AJAXEXCEPTION = function(config) {
313 config.name = config.name || 'Error';
314 config.closeButton = true;
315 AJAXEXCEPTION.superclass.constructor.apply(this, [config]);
8505d925 316};
6db3eee0
SH
317Y.extend(AJAXEXCEPTION, DIALOGUE, {
318 _keypress : null,
319 initializer : function(config) {
320 this.get(BASE).addClass('moodle-dialogue-exception');
321 this.setStdModContent(Y.WidgetStdMod.HEADER, config.name, Y.WidgetStdMod.REPLACE);
322 var content = C('<div class="moodle-ajaxexception"></div>')
323 .append(C('<div class="moodle-exception-message">'+this.get('error')+'</div>'))
324 .append(C('<div class="moodle-exception-param hidden param-debuginfo"><label>URL:</label> '+this.get('reproductionlink')+'</div>'))
325 .append(C('<div class="moodle-exception-param hidden param-debuginfo"><label>Debug info:</label> '+this.get('debuginfo')+'</div>'))
326 .append(C('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>'+this.get('stacktrace')+'</pre></div>'));
327 if (M.cfg.developerdebug) {
328 content.all('.moodle-exception-param').removeClass('hidden');
329 }
330 this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
331
332 var self = this;
333 var delay = this.get('hideTimeoutDelay');
334 if (delay) {
335 this._hideTimeout = setTimeout(function(){self.hide();}, delay);
336 }
337 this.after('visibleChange', this.visibilityChanged, this);
338 this._keypress = Y.on('key', this.hide, window, 'down:13, 27', this);
339 this.centerDialogue();
340 },
341 visibilityChanged : function(e) {
342 if (e.attrName == 'visible' && e.prevVal && !e.newVal) {
343 var self = this;
344 this._keypress.detach();
345 setTimeout(function(){self.destroy();}, 1000);
346 }
347 }
348}, {
349 NAME : AJAXEXCEPTION_NAME,
350 CSS_PREFIX : DIALOGUE_PREFIX,
351 ATTRS : {
352 error : {
353 validator : Y.Lang.isString,
354 value : 'Unknown error'
355 },
356 debuginfo : {
357 value : null
358 },
359 stacktrace : {
360 value : null
361 },
362 reproductionlink : {
363 setter : function(link) {
364 if (link !== null) {
365 link = '<a href="'+link+'">'+link.replace(M.cfg.wwwroot, '')+'</a>';
366 }
367 return link;
368 },
369 value : null
370 },
371 hideTimeoutDelay : {
372 validator : Y.Lang.isNumber,
373 value : null
374 }
375 }
376});
377
378M.core = M.core || {};
379M.core.dialogue = DIALOGUE;
380M.core.alert = ALERT;
381M.core.confirm = CONFIRM;
382M.core.exception = EXCEPTION;
383M.core.ajaxException = AJAXEXCEPTION;
384
06a78ea6 385}, '@VERSION@', {requires:['base','node','overlay','event-key', 'moodle-enrol-notification-skin', 'dd-plugin']});