Merge branch 'MDL-40678-m' of git://github.com/andrewnicols/moodle

This commit is contained in:
Sam Hemelryk 2013-07-30 08:55:35 +12:00
commit 73b4c1da84
28 changed files with 2552 additions and 1208 deletions

View File

@ -83,6 +83,16 @@ Misc:
* detect_munged_arguments() -> clean_param([...], PARAM_FILE) * detect_munged_arguments() -> clean_param([...], PARAM_FILE)
* mygroupid() -> groups_get_all_groups() * mygroupid() -> groups_get_all_groups()
YUI:
* moodle-core-notification has been deprecated with a recommendation of
using its subclasses instead. This is to allow for reduced page
transport costs. Current subclasses include:
* dialogue
* alert
* confirm
* exception
* ajaxexception
=== 2.5.1 === === 2.5.1 ===
* New get_course() function for use when obtaining the course record from database. Will * New get_course() function for use when obtaining the course record from database. Will

View File

@ -0,0 +1,170 @@
YUI.add('moodle-core-notification-ajaxexception', function (Y, NAME) {
var DIALOGUE_PREFIX,
BASE,
COUNT,
CONFIRMYES,
CONFIRMNO,
TITLE,
QUESTION,
CSS;
DIALOGUE_PREFIX = 'moodle-dialogue',
BASE = 'notificationBase',
COUNT = 0,
CONFIRMYES = 'yesLabel',
CONFIRMNO = 'noLabel',
TITLE = 'title',
QUESTION = 'question',
CSS = {
BASE : 'moodle-dialogue-base',
WRAP : 'moodle-dialogue-wrap',
HEADER : 'moodle-dialogue-hd',
BODY : 'moodle-dialogue-bd',
CONTENT : 'moodle-dialogue-content',
FOOTER : 'moodle-dialogue-ft',
HIDDEN : 'hidden',
LIGHTBOX : 'moodle-dialogue-lightbox'
};
// Set up the namespace once.
M.core = M.core || {};
/**
* A dialogue type designed to display an appropriate error when an error
* thrown in the Moodle codebase was reported during an AJAX request.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-ajaxexception
*/
var AJAXEXCEPTION_NAME = 'Moodle AJAX exception',
AJAXEXCEPTION;
/**
* Extends core Dialogue to show the exception dialogue.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.ajaxException
* @extends M.core.dialogue
*/
AJAXEXCEPTION = function(config) {
config.name = config.name || 'Error';
config.closeButton = true;
AJAXEXCEPTION.superclass.constructor.apply(this, [config]);
};
Y.extend(AJAXEXCEPTION, M.core.dialogue, {
_keypress : null,
initializer : function(config) {
var content,
self = this,
delay = this.get('hideTimeoutDelay');
this.get(BASE).addClass('moodle-dialogue-exception');
this.setStdModContent(Y.WidgetStdMod.HEADER,
'<h1 id="moodle-dialogue-'+this.get('COUNT')+'-header-text">' + config.name + '</h1>', Y.WidgetStdMod.REPLACE);
content = Y.Node.create('<div class="moodle-ajaxexception"></div>')
.append(Y.Node.create('<div class="moodle-exception-message">'+this.get('error')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-debuginfo"><label>URL:</label> ' +
this.get('reproductionlink')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-debuginfo"><label>Debug info:</label> ' +
this.get('debuginfo')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>' +
this.get('stacktrace')+'</pre></div>'));
if (M.cfg.developerdebug) {
content.all('.moodle-exception-param').removeClass('hidden');
}
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
if (delay) {
this._hideTimeout = setTimeout(function(){self.hide();}, delay);
}
this.after('visibleChange', this.visibilityChanged, this);
this._keypress = Y.on('key', this.hide, window, 'down:13, 27', this);
this.centerDialogue();
},
visibilityChanged : function(e) {
if (e.attrName === 'visible' && e.prevVal && !e.newVal) {
var self = this;
this._keypress.detach();
setTimeout(function(){self.destroy();}, 1000);
}
}
}, {
NAME : AJAXEXCEPTION_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
/**
* The error message given in the exception.
*
* @attribute error
* @type String
* @default 'Unknown error'
* @optional
*/
error : {
validator : Y.Lang.isString,
value : 'Unknown error'
},
/**
* Any additional debug information given in the exception.
*
* @attribute stacktrace
* @type String|null
* @default null
* @optional
*/
debuginfo : {
value : null
},
/**
* The complete stack trace provided in the exception.
*
* @attribute stacktrace
* @type String|null
* @default null
* @optional
*/
stacktrace : {
value : null
},
/**
* A link which may be used by support staff to replicate the issue.
*
* @attribute reproductionlink
* @type String
* @default null
* @optional
*/
reproductionlink : {
setter : function(link) {
if (link !== null) {
link = '<a href="'+link+'">'+link.replace(M.cfg.wwwroot, '')+'</a>';
}
return link;
},
value : null
},
/**
* If set, the dialogue is hidden after the specified timeout period.
*
* @attribute hideTimeoutDelay
* @type Number
* @default null
* @optional
*/
hideTimeoutDelay : {
validator : Y.Lang.isNumber,
value : null
}
}
});
M.core.ajaxException = AJAXEXCEPTION;
}, '@VERSION@', {"requires": ["moodle-core-notification-dialogue"]});

View File

@ -0,0 +1 @@
YUI.add("moodle-core-notification-ajaxexception",function(e,t){var n,r,i,s,o,u,a,f;n="moodle-dialogue",r="notificationBase",i=0,s="yesLabel",o="noLabel",u="title",a="question",f={BASE:"moodle-dialogue-base",WRAP:"moodle-dialogue-wrap",HEADER:"moodle-dialogue-hd",BODY:"moodle-dialogue-bd",CONTENT:"moodle-dialogue-content",FOOTER:"moodle-dialogue-ft",HIDDEN:"hidden",LIGHTBOX:"moodle-dialogue-lightbox"},M.core=M.core||{};var l="Moodle AJAX exception",c;c=function(e){e.name=e.name||"Error",e.closeButton=!0,c.superclass.constructor.apply(this,[e])},e.extend(c,M.core.dialogue,{_keypress:null,initializer:function(t){var n,i=this,s=this.get("hideTimeoutDelay");this.get(r).addClass("moodle-dialogue-exception"),this.setStdModContent(e.WidgetStdMod.HEADER,'<h1 id="moodle-dialogue-'+this.get("COUNT")+'-header-text">'+t.name+"</h1>",e.WidgetStdMod.REPLACE),n=e.Node.create('<div class="moodle-ajaxexception"></div>').append(e.Node.create('<div class="moodle-exception-message">'+this.get("error")+"</div>")).append(e.Node.create('<div class="moodle-exception-param hidden param-debuginfo"><label>URL:</label> '+this.get("reproductionlink")+"</div>")).append(e.Node.create('<div class="moodle-exception-param hidden param-debuginfo"><label>Debug info:</label> '+this.get("debuginfo")+"</div>")).append(e.Node.create('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>'+this.get("stacktrace")+"</pre></div>")),M.cfg.developerdebug&&n.all(".moodle-exception-param").removeClass("hidden"),this.setStdModContent(e.WidgetStdMod.BODY,n,e.WidgetStdMod.REPLACE),s&&(this._hideTimeout=setTimeout(function(){i.hide()},s)),this.after("visibleChange",this.visibilityChanged,this),this._keypress=e.on("key",this.hide,window,"down:13, 27",this),this.centerDialogue()},visibilityChanged:function(e){if(e.attrName==="visible"&&e.prevVal&&!e.newVal){var t=this;this._keypress.detach(),setTimeout(function(){t.destroy()},1e3)}}},{NAME:l,CSS_PREFIX:n,ATTRS:{error:{validator:e.Lang.isString,value:"Unknown error"},debuginfo:{value:null},stacktrace:{value:null},reproductionlink:{setter:function(e){return e!==null&&(e='<a href="'+e+'">'+e.replace(M.cfg.wwwroot,"")+"</a>"),e},value:null},hideTimeoutDelay:{validator:e.Lang.isNumber,value:null}}}),M.core.ajaxException=c},"@VERSION@",{requires:["moodle-core-notification-dialogue"]});

View File

@ -0,0 +1,170 @@
YUI.add('moodle-core-notification-ajaxexception', function (Y, NAME) {
var DIALOGUE_PREFIX,
BASE,
COUNT,
CONFIRMYES,
CONFIRMNO,
TITLE,
QUESTION,
CSS;
DIALOGUE_PREFIX = 'moodle-dialogue',
BASE = 'notificationBase',
COUNT = 0,
CONFIRMYES = 'yesLabel',
CONFIRMNO = 'noLabel',
TITLE = 'title',
QUESTION = 'question',
CSS = {
BASE : 'moodle-dialogue-base',
WRAP : 'moodle-dialogue-wrap',
HEADER : 'moodle-dialogue-hd',
BODY : 'moodle-dialogue-bd',
CONTENT : 'moodle-dialogue-content',
FOOTER : 'moodle-dialogue-ft',
HIDDEN : 'hidden',
LIGHTBOX : 'moodle-dialogue-lightbox'
};
// Set up the namespace once.
M.core = M.core || {};
/**
* A dialogue type designed to display an appropriate error when an error
* thrown in the Moodle codebase was reported during an AJAX request.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-ajaxexception
*/
var AJAXEXCEPTION_NAME = 'Moodle AJAX exception',
AJAXEXCEPTION;
/**
* Extends core Dialogue to show the exception dialogue.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.ajaxException
* @extends M.core.dialogue
*/
AJAXEXCEPTION = function(config) {
config.name = config.name || 'Error';
config.closeButton = true;
AJAXEXCEPTION.superclass.constructor.apply(this, [config]);
};
Y.extend(AJAXEXCEPTION, M.core.dialogue, {
_keypress : null,
initializer : function(config) {
var content,
self = this,
delay = this.get('hideTimeoutDelay');
this.get(BASE).addClass('moodle-dialogue-exception');
this.setStdModContent(Y.WidgetStdMod.HEADER,
'<h1 id="moodle-dialogue-'+this.get('COUNT')+'-header-text">' + config.name + '</h1>', Y.WidgetStdMod.REPLACE);
content = Y.Node.create('<div class="moodle-ajaxexception"></div>')
.append(Y.Node.create('<div class="moodle-exception-message">'+this.get('error')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-debuginfo"><label>URL:</label> ' +
this.get('reproductionlink')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-debuginfo"><label>Debug info:</label> ' +
this.get('debuginfo')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>' +
this.get('stacktrace')+'</pre></div>'));
if (M.cfg.developerdebug) {
content.all('.moodle-exception-param').removeClass('hidden');
}
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
if (delay) {
this._hideTimeout = setTimeout(function(){self.hide();}, delay);
}
this.after('visibleChange', this.visibilityChanged, this);
this._keypress = Y.on('key', this.hide, window, 'down:13, 27', this);
this.centerDialogue();
},
visibilityChanged : function(e) {
if (e.attrName === 'visible' && e.prevVal && !e.newVal) {
var self = this;
this._keypress.detach();
setTimeout(function(){self.destroy();}, 1000);
}
}
}, {
NAME : AJAXEXCEPTION_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
/**
* The error message given in the exception.
*
* @attribute error
* @type String
* @default 'Unknown error'
* @optional
*/
error : {
validator : Y.Lang.isString,
value : 'Unknown error'
},
/**
* Any additional debug information given in the exception.
*
* @attribute stacktrace
* @type String|null
* @default null
* @optional
*/
debuginfo : {
value : null
},
/**
* The complete stack trace provided in the exception.
*
* @attribute stacktrace
* @type String|null
* @default null
* @optional
*/
stacktrace : {
value : null
},
/**
* A link which may be used by support staff to replicate the issue.
*
* @attribute reproductionlink
* @type String
* @default null
* @optional
*/
reproductionlink : {
setter : function(link) {
if (link !== null) {
link = '<a href="'+link+'">'+link.replace(M.cfg.wwwroot, '')+'</a>';
}
return link;
},
value : null
},
/**
* If set, the dialogue is hidden after the specified timeout period.
*
* @attribute hideTimeoutDelay
* @type Number
* @default null
* @optional
*/
hideTimeoutDelay : {
validator : Y.Lang.isNumber,
value : null
}
}
});
M.core.ajaxException = AJAXEXCEPTION;
}, '@VERSION@', {"requires": ["moodle-core-notification-dialogue"]});

View File

@ -0,0 +1,129 @@
YUI.add('moodle-core-notification-alert', function (Y, NAME) {
var DIALOGUE_PREFIX,
BASE,
COUNT,
CONFIRMYES,
CONFIRMNO,
TITLE,
QUESTION,
CSS;
DIALOGUE_PREFIX = 'moodle-dialogue',
BASE = 'notificationBase',
COUNT = 0,
CONFIRMYES = 'yesLabel',
CONFIRMNO = 'noLabel',
TITLE = 'title',
QUESTION = 'question',
CSS = {
BASE : 'moodle-dialogue-base',
WRAP : 'moodle-dialogue-wrap',
HEADER : 'moodle-dialogue-hd',
BODY : 'moodle-dialogue-bd',
CONTENT : 'moodle-dialogue-content',
FOOTER : 'moodle-dialogue-ft',
HIDDEN : 'hidden',
LIGHTBOX : 'moodle-dialogue-lightbox'
};
// Set up the namespace once.
M.core = M.core || {};
/**
* A dialogue type designed to display an alert to the user.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-alert
*/
var ALERT_NAME = 'Moodle alert',
ALERT;
/**
* Extends core Dialogue to show the alert dialogue.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.alert
* @extends M.core.dialogue
*/
ALERT = function(config) {
config.closeButton = false;
ALERT.superclass.constructor.apply(this, [config]);
};
Y.extend(ALERT, M.core.dialogue, {
_enterKeypress : null,
initializer : function() {
this.publish('complete');
var yes = Y.Node.create('<input type="button" id="id_yuialertconfirm-' + this.get('COUNT') + '" value="'+this.get(CONFIRMYES)+'" />'),
content = Y.Node.create('<div class="confirmation-dialogue"></div>')
.append(Y.Node.create('<div class="confirmation-message">'+this.get('message')+'</div>'))
.append(Y.Node.create('<div class="confirmation-buttons"></div>')
.append(yes));
this.get(BASE).addClass('moodle-dialogue-confirm');
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
this.setStdModContent(Y.WidgetStdMod.HEADER,
'<h1 id="moodle-dialogue-'+this.get('COUNT')+'-header-text">' + this.get(TITLE) + '</h1>', Y.WidgetStdMod.REPLACE);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._enterKeypress = Y.on('key', this.submit, window, 'down:13', this);
yes.on('click', this.submit, this);
},
submit : function() {
this._enterKeypress.detach();
this.fire('complete');
this.hide();
this.destroy();
}
}, {
NAME : ALERT_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
/**
* The title of the alert.
*
* @attribute title
* @type String
* @default 'Alert'
*/
title : {
validator : Y.Lang.isString,
value : 'Alert'
},
/**
* The message of the alert.
*
* @attribute message
* @type String
* @default 'Confirm'
*/
message : {
validator : Y.Lang.isString,
value : 'Confirm'
},
/**
* The button text to use to accept the alert.
*
* @attribute yesLabel
* @type String
* @default 'Ok'
*/
yesLabel : {
validator : Y.Lang.isString,
setter : function(txt) {
if (!txt) {
txt = 'Ok';
}
return txt;
},
value : 'Ok'
}
}
});
M.core.alert = ALERT;
}, '@VERSION@', {"requires": ["moodle-core-notification-dialogue"]});

View File

@ -0,0 +1 @@
YUI.add("moodle-core-notification-alert",function(e,t){var n,r,i,s,o,u,a,f;n="moodle-dialogue",r="notificationBase",i=0,s="yesLabel",o="noLabel",u="title",a="question",f={BASE:"moodle-dialogue-base",WRAP:"moodle-dialogue-wrap",HEADER:"moodle-dialogue-hd",BODY:"moodle-dialogue-bd",CONTENT:"moodle-dialogue-content",FOOTER:"moodle-dialogue-ft",HIDDEN:"hidden",LIGHTBOX:"moodle-dialogue-lightbox"},M.core=M.core||{};var l="Moodle alert",c;c=function(e){e.closeButton=!1,c.superclass.constructor.apply(this,[e])},e.extend(c,M.core.dialogue,{_enterKeypress:null,initializer:function(){this.publish("complete");var t=e.Node.create('<input type="button" id="id_yuialertconfirm-'+this.get("COUNT")+'" value="'+this.get(s)+'" />'),n=e.Node.create('<div class="confirmation-dialogue"></div>').append(e.Node.create('<div class="confirmation-message">'+this.get("message")+"</div>")).append(e.Node.create('<div class="confirmation-buttons"></div>').append(t));this.get(r).addClass("moodle-dialogue-confirm"),this.setStdModContent(e.WidgetStdMod.BODY,n,e.WidgetStdMod.REPLACE),this.setStdModContent(e.WidgetStdMod.HEADER,'<h1 id="moodle-dialogue-'+this.get("COUNT")+'-header-text">'+this.get(u)+"</h1>",e.WidgetStdMod.REPLACE),this.after("destroyedChange",function(){this.get(r).remove()},this),this._enterKeypress=e.on("key",this.submit,window,"down:13",this),t.on("click",this.submit,this)},submit:function(){this._enterKeypress.detach(),this.fire("complete"),this.hide(),this.destroy()}},{NAME:l,CSS_PREFIX:n,ATTRS:{title:{validator:e.Lang.isString,value:"Alert"},message:{validator:e.Lang.isString,value:"Confirm"},yesLabel:{validator:e.Lang.isString,setter:function(e){return e||(e="Ok"),e},value:"Ok"}}}),M.core.alert=c},"@VERSION@",{requires:["moodle-core-notification-dialogue"]});

View File

@ -0,0 +1,129 @@
YUI.add('moodle-core-notification-alert', function (Y, NAME) {
var DIALOGUE_PREFIX,
BASE,
COUNT,
CONFIRMYES,
CONFIRMNO,
TITLE,
QUESTION,
CSS;
DIALOGUE_PREFIX = 'moodle-dialogue',
BASE = 'notificationBase',
COUNT = 0,
CONFIRMYES = 'yesLabel',
CONFIRMNO = 'noLabel',
TITLE = 'title',
QUESTION = 'question',
CSS = {
BASE : 'moodle-dialogue-base',
WRAP : 'moodle-dialogue-wrap',
HEADER : 'moodle-dialogue-hd',
BODY : 'moodle-dialogue-bd',
CONTENT : 'moodle-dialogue-content',
FOOTER : 'moodle-dialogue-ft',
HIDDEN : 'hidden',
LIGHTBOX : 'moodle-dialogue-lightbox'
};
// Set up the namespace once.
M.core = M.core || {};
/**
* A dialogue type designed to display an alert to the user.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-alert
*/
var ALERT_NAME = 'Moodle alert',
ALERT;
/**
* Extends core Dialogue to show the alert dialogue.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.alert
* @extends M.core.dialogue
*/
ALERT = function(config) {
config.closeButton = false;
ALERT.superclass.constructor.apply(this, [config]);
};
Y.extend(ALERT, M.core.dialogue, {
_enterKeypress : null,
initializer : function() {
this.publish('complete');
var yes = Y.Node.create('<input type="button" id="id_yuialertconfirm-' + this.get('COUNT') + '" value="'+this.get(CONFIRMYES)+'" />'),
content = Y.Node.create('<div class="confirmation-dialogue"></div>')
.append(Y.Node.create('<div class="confirmation-message">'+this.get('message')+'</div>'))
.append(Y.Node.create('<div class="confirmation-buttons"></div>')
.append(yes));
this.get(BASE).addClass('moodle-dialogue-confirm');
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
this.setStdModContent(Y.WidgetStdMod.HEADER,
'<h1 id="moodle-dialogue-'+this.get('COUNT')+'-header-text">' + this.get(TITLE) + '</h1>', Y.WidgetStdMod.REPLACE);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._enterKeypress = Y.on('key', this.submit, window, 'down:13', this);
yes.on('click', this.submit, this);
},
submit : function() {
this._enterKeypress.detach();
this.fire('complete');
this.hide();
this.destroy();
}
}, {
NAME : ALERT_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
/**
* The title of the alert.
*
* @attribute title
* @type String
* @default 'Alert'
*/
title : {
validator : Y.Lang.isString,
value : 'Alert'
},
/**
* The message of the alert.
*
* @attribute message
* @type String
* @default 'Confirm'
*/
message : {
validator : Y.Lang.isString,
value : 'Confirm'
},
/**
* The button text to use to accept the alert.
*
* @attribute yesLabel
* @type String
* @default 'Ok'
*/
yesLabel : {
validator : Y.Lang.isString,
setter : function(txt) {
if (!txt) {
txt = 'Ok';
}
return txt;
},
value : 'Ok'
}
}
});
M.core.alert = ALERT;
}, '@VERSION@', {"requires": ["moodle-core-notification-dialogue"]});

View File

@ -0,0 +1,148 @@
YUI.add('moodle-core-notification-confirm', function (Y, NAME) {
var DIALOGUE_PREFIX,
BASE,
COUNT,
CONFIRMYES,
CONFIRMNO,
TITLE,
QUESTION,
CSS;
DIALOGUE_PREFIX = 'moodle-dialogue',
BASE = 'notificationBase',
COUNT = 0,
CONFIRMYES = 'yesLabel',
CONFIRMNO = 'noLabel',
TITLE = 'title',
QUESTION = 'question',
CSS = {
BASE : 'moodle-dialogue-base',
WRAP : 'moodle-dialogue-wrap',
HEADER : 'moodle-dialogue-hd',
BODY : 'moodle-dialogue-bd',
CONTENT : 'moodle-dialogue-content',
FOOTER : 'moodle-dialogue-ft',
HIDDEN : 'hidden',
LIGHTBOX : 'moodle-dialogue-lightbox'
};
// Set up the namespace once.
M.core = M.core || {};
/**
* A dialogue type designed to display a confirmation to the user.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-confirm
*/
var CONFIRM_NAME = 'Moodle confirmation dialogue',
CONFIRM;
/**
* Extends core Dialogue to show the confirmation dialogue.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.confirm
* @extends M.core.dialogue
*/
CONFIRM = function(config) {
CONFIRM.superclass.constructor.apply(this, [config]);
};
Y.extend(CONFIRM, M.core.dialogue, {
_enterKeypress : null,
_escKeypress : null,
initializer : function() {
this.publish('complete');
this.publish('complete-yes');
this.publish('complete-no');
var yes = Y.Node.create('<input type="button" id="id_yuiconfirmyes-' + this.get('COUNT') + '" value="'+this.get(CONFIRMYES)+'" />'),
no = Y.Node.create('<input type="button" id="id_yuiconfirmno-' + this.get('COUNT') + '" value="'+this.get(CONFIRMNO)+'" />'),
content = Y.Node.create('<div class="confirmation-dialogue"></div>')
.append(Y.Node.create('<div class="confirmation-message">'+this.get(QUESTION)+'</div>'))
.append(Y.Node.create('<div class="confirmation-buttons"></div>')
.append(yes)
.append(no));
this.get(BASE).addClass('moodle-dialogue-confirm');
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
this.setStdModContent(Y.WidgetStdMod.HEADER,
'<h1 id="moodle-dialogue-'+this.get('COUNT')+'-header-text">' + this.get(TITLE) + '</h1>', Y.WidgetStdMod.REPLACE);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._enterKeypress = Y.on('key', this.submit, window, 'down:13', this, true);
this._escKeypress = Y.on('key', this.submit, window, 'down:27', this, false);
yes.on('click', this.submit, this, true);
no.on('click', this.submit, this, false);
},
submit : function(e, outcome) {
this._enterKeypress.detach();
this._escKeypress.detach();
this.fire('complete', outcome);
if (outcome) {
this.fire('complete-yes');
} else {
this.fire('complete-no');
}
this.hide();
this.destroy();
}
}, {
NAME : CONFIRM_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
/**
* The button text to use to accept the confirmation.
*
* @attribute yesLabel
* @type String
* @default 'Yes'
*/
yesLabel : {
validator : Y.Lang.isString,
value : 'Yes'
},
/**
* The button text to use to reject the confirmation.
*
* @attribute noLabel
* @type String
* @default 'No'
*/
noLabel : {
validator : Y.Lang.isString,
value : 'No'
},
/**
* The title of the dialogue.
*
* @attribute title
* @type String
* @default 'Confirm'
*/
title : {
validator : Y.Lang.isString,
value : 'Confirm'
},
/**
* The question posed by the dialogue.
*
* @attribute question
* @type String
* @default 'Are you sure?'
*/
question : {
validator : Y.Lang.isString,
value : 'Are you sure?'
}
}
});
Y.augment(CONFIRM, Y.EventTarget);
M.core.confirm = CONFIRM;
}, '@VERSION@', {"requires": ["moodle-core-notification-dialogue"]});

View File

@ -0,0 +1 @@
YUI.add("moodle-core-notification-confirm",function(e,t){var n,r,i,s,o,u,a,f;n="moodle-dialogue",r="notificationBase",i=0,s="yesLabel",o="noLabel",u="title",a="question",f={BASE:"moodle-dialogue-base",WRAP:"moodle-dialogue-wrap",HEADER:"moodle-dialogue-hd",BODY:"moodle-dialogue-bd",CONTENT:"moodle-dialogue-content",FOOTER:"moodle-dialogue-ft",HIDDEN:"hidden",LIGHTBOX:"moodle-dialogue-lightbox"},M.core=M.core||{};var l="Moodle confirmation dialogue",c;c=function(e){c.superclass.constructor.apply(this,[e])},e.extend(c,M.core.dialogue,{_enterKeypress:null,_escKeypress:null,initializer:function(){this.publish("complete"),this.publish("complete-yes"),this.publish("complete-no");var t=e.Node.create('<input type="button" id="id_yuiconfirmyes-'+this.get("COUNT")+'" value="'+this.get(s)+'" />'),n=e.Node.create('<input type="button" id="id_yuiconfirmno-'+this.get("COUNT")+'" value="'+this.get(o)+'" />'),i=e.Node.create('<div class="confirmation-dialogue"></div>').append(e.Node.create('<div class="confirmation-message">'+this.get(a)+"</div>")).append(e.Node.create('<div class="confirmation-buttons"></div>').append(t).append(n));this.get(r).addClass("moodle-dialogue-confirm"),this.setStdModContent(e.WidgetStdMod.BODY,i,e.WidgetStdMod.REPLACE),this.setStdModContent(e.WidgetStdMod.HEADER,'<h1 id="moodle-dialogue-'+this.get("COUNT")+'-header-text">'+this.get(u)+"</h1>",e.WidgetStdMod.REPLACE),this.after("destroyedChange",function(){this.get(r).remove()},this),this._enterKeypress=e.on("key",this.submit,window,"down:13",this,!0),this._escKeypress=e.on("key",this.submit,window,"down:27",this,!1),t.on("click",this.submit,this,!0),n.on("click",this.submit,this,!1)},submit:function(e,t){this._enterKeypress.detach(),this._escKeypress.detach(),this.fire("complete",t),t?this.fire("complete-yes"):this.fire("complete-no"),this.hide(),this.destroy()}},{NAME:l,CSS_PREFIX:n,ATTRS:{yesLabel:{validator:e.Lang.isString,value:"Yes"},noLabel:{validator:e.Lang.isString,value:"No"},title:{validator:e.Lang.isString,value:"Confirm"},question:{validator:e.Lang.isString,value:"Are you sure?"}}}),e.augment(c,e.EventTarget),M.core.confirm=c},"@VERSION@",{requires:["moodle-core-notification-dialogue"]});

View File

@ -0,0 +1,148 @@
YUI.add('moodle-core-notification-confirm', function (Y, NAME) {
var DIALOGUE_PREFIX,
BASE,
COUNT,
CONFIRMYES,
CONFIRMNO,
TITLE,
QUESTION,
CSS;
DIALOGUE_PREFIX = 'moodle-dialogue',
BASE = 'notificationBase',
COUNT = 0,
CONFIRMYES = 'yesLabel',
CONFIRMNO = 'noLabel',
TITLE = 'title',
QUESTION = 'question',
CSS = {
BASE : 'moodle-dialogue-base',
WRAP : 'moodle-dialogue-wrap',
HEADER : 'moodle-dialogue-hd',
BODY : 'moodle-dialogue-bd',
CONTENT : 'moodle-dialogue-content',
FOOTER : 'moodle-dialogue-ft',
HIDDEN : 'hidden',
LIGHTBOX : 'moodle-dialogue-lightbox'
};
// Set up the namespace once.
M.core = M.core || {};
/**
* A dialogue type designed to display a confirmation to the user.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-confirm
*/
var CONFIRM_NAME = 'Moodle confirmation dialogue',
CONFIRM;
/**
* Extends core Dialogue to show the confirmation dialogue.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.confirm
* @extends M.core.dialogue
*/
CONFIRM = function(config) {
CONFIRM.superclass.constructor.apply(this, [config]);
};
Y.extend(CONFIRM, M.core.dialogue, {
_enterKeypress : null,
_escKeypress : null,
initializer : function() {
this.publish('complete');
this.publish('complete-yes');
this.publish('complete-no');
var yes = Y.Node.create('<input type="button" id="id_yuiconfirmyes-' + this.get('COUNT') + '" value="'+this.get(CONFIRMYES)+'" />'),
no = Y.Node.create('<input type="button" id="id_yuiconfirmno-' + this.get('COUNT') + '" value="'+this.get(CONFIRMNO)+'" />'),
content = Y.Node.create('<div class="confirmation-dialogue"></div>')
.append(Y.Node.create('<div class="confirmation-message">'+this.get(QUESTION)+'</div>'))
.append(Y.Node.create('<div class="confirmation-buttons"></div>')
.append(yes)
.append(no));
this.get(BASE).addClass('moodle-dialogue-confirm');
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
this.setStdModContent(Y.WidgetStdMod.HEADER,
'<h1 id="moodle-dialogue-'+this.get('COUNT')+'-header-text">' + this.get(TITLE) + '</h1>', Y.WidgetStdMod.REPLACE);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._enterKeypress = Y.on('key', this.submit, window, 'down:13', this, true);
this._escKeypress = Y.on('key', this.submit, window, 'down:27', this, false);
yes.on('click', this.submit, this, true);
no.on('click', this.submit, this, false);
},
submit : function(e, outcome) {
this._enterKeypress.detach();
this._escKeypress.detach();
this.fire('complete', outcome);
if (outcome) {
this.fire('complete-yes');
} else {
this.fire('complete-no');
}
this.hide();
this.destroy();
}
}, {
NAME : CONFIRM_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
/**
* The button text to use to accept the confirmation.
*
* @attribute yesLabel
* @type String
* @default 'Yes'
*/
yesLabel : {
validator : Y.Lang.isString,
value : 'Yes'
},
/**
* The button text to use to reject the confirmation.
*
* @attribute noLabel
* @type String
* @default 'No'
*/
noLabel : {
validator : Y.Lang.isString,
value : 'No'
},
/**
* The title of the dialogue.
*
* @attribute title
* @type String
* @default 'Confirm'
*/
title : {
validator : Y.Lang.isString,
value : 'Confirm'
},
/**
* The question posed by the dialogue.
*
* @attribute question
* @type String
* @default 'Are you sure?'
*/
question : {
validator : Y.Lang.isString,
value : 'Are you sure?'
}
}
});
Y.augment(CONFIRM, Y.EventTarget);
M.core.confirm = CONFIRM;
}, '@VERSION@', {"requires": ["moodle-core-notification-dialogue"]});

View File

@ -0,0 +1,214 @@
YUI.add('moodle-core-notification-dialogue', function (Y, NAME) {
var DIALOGUE_PREFIX,
BASE,
COUNT,
CONFIRMYES,
CONFIRMNO,
TITLE,
QUESTION,
CSS;
DIALOGUE_PREFIX = 'moodle-dialogue',
BASE = 'notificationBase',
COUNT = 0,
CONFIRMYES = 'yesLabel',
CONFIRMNO = 'noLabel',
TITLE = 'title',
QUESTION = 'question',
CSS = {
BASE : 'moodle-dialogue-base',
WRAP : 'moodle-dialogue-wrap',
HEADER : 'moodle-dialogue-hd',
BODY : 'moodle-dialogue-bd',
CONTENT : 'moodle-dialogue-content',
FOOTER : 'moodle-dialogue-ft',
HIDDEN : 'hidden',
LIGHTBOX : 'moodle-dialogue-lightbox'
};
// Set up the namespace once.
M.core = M.core || {};
/**
* The generic dialogue class for use in Moodle.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-dialogue
*/
var DIALOGUE_NAME = 'Moodle dialogue',
DIALOGUE;
/**
* A re-usable dialogue box with Moodle classes applied.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.dialogue
* @extends Y.Panel
*/
DIALOGUE = function(config) {
COUNT++;
var id = 'moodle-dialogue-'+COUNT;
config.notificationBase =
Y.Node.create('<div class="'+CSS.BASE+'">')
.append(Y.Node.create('<div id="'+id+'" role="dialog" aria-labelledby="'+id+'-header-text" class="'+CSS.WRAP+'"></div>')
.append(Y.Node.create('<div class="'+CSS.HEADER+' yui3-widget-hd"></div>'))
.append(Y.Node.create('<div class="'+CSS.BODY+' yui3-widget-bd"></div>'))
.append(Y.Node.create('<div class="'+CSS.FOOTER+' yui3-widget-ft"></div>')));
Y.one(document.body).append(config.notificationBase);
config.srcNode = '#'+id;
config.width = config.width || '400px';
config.visible = config.visible || false;
config.center = config.centered || true;
config.centered = false;
config.COUNT = COUNT;
// lightbox param to keep the stable versions API.
if (config.lightbox !== false) {
config.modal = true;
}
delete config.lightbox;
// closeButton param to keep the stable versions API.
if (config.closeButton === false) {
config.buttons = null;
} else {
config.buttons = [
{
section: Y.WidgetStdMod.HEADER,
classNames: 'closebutton',
action: function () {
this.hide();
}
}
];
}
DIALOGUE.superclass.constructor.apply(this, [config]);
if (config.closeButton !== false) {
// The buttons constructor does not allow custom attributes
this.get('buttons').header[0].setAttribute('title', this.get('closeButtonTitle'));
}
};
Y.extend(DIALOGUE, Y.Panel, {
initializer : function() {
this.after('visibleChange', this.visibilityChanged, this);
this.render();
this.show();
this.set('COUNT', COUNT);
// Workaround upstream YUI bug http://yuilibrary.com/projects/yui3/ticket/2532507
// and allow setting of z-index in theme.
this.get('boundingBox').setStyle('zIndex', null);
},
visibilityChanged : function(e) {
var titlebar;
if (e.attrName === 'visible') {
this.get('maskNode').addClass(CSS.LIGHTBOX);
if (this.get('center') && !e.prevVal && e.newVal) {
this.centerDialogue();
}
if (this.get('draggable')) {
titlebar = '#' + this.get('id') + ' .' + CSS.HEADER;
this.plug(Y.Plugin.Drag, {handles : [titlebar]});
Y.one(titlebar).setStyle('cursor', 'move');
}
}
},
centerDialogue : function() {
var bb = this.get('boundingBox'),
hidden = bb.hasClass(DIALOGUE_PREFIX+'-hidden'),
x, y;
if (hidden) {
bb.setStyle('top', '-1000px').removeClass(DIALOGUE_PREFIX+'-hidden');
}
x = Math.max(Math.round((bb.get('winWidth') - bb.get('offsetWidth'))/2), 15);
y = Math.max(Math.round((bb.get('winHeight') - bb.get('offsetHeight'))/2), 15) + Y.one(window).get('scrollTop');
if (hidden) {
bb.addClass(DIALOGUE_PREFIX+'-hidden');
}
bb.setStyle('left', x).setStyle('top', y);
}
}, {
NAME : DIALOGUE_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
notificationBase : {
},
/**
* Whether to display the dialogue modally and with a
* lightbox style.
*
* @attribute lightbox
* @type Boolean
* @default true
*/
lightbox : {
validator : Y.Lang.isBoolean,
value : true
},
/**
* Whether to display a close button on the dialogue.
*
* Note, we do not recommend hiding the close button as this has
* potential accessibility concerns.
*
* @attribute closeButton
* @type Boolean
* @default true
*/
closeButton : {
validator : Y.Lang.isBoolean,
value : true
},
/**
* The title for the close button if one is to be shown.
*
* @attribute closeButtonTitle
* @type String
* @default 'Close'
*/
closeButtonTitle : {
validator : Y.Lang.isString,
value : 'Close'
},
/**
* Whether to display the dialogue centrally on the screen.
*
* @attribute center
* @type Boolean
* @default true
*/
center : {
validator : Y.Lang.isBoolean,
value : true
},
/**
* Whether to make the dialogue movable around the page.
*
* @attribute draggable
* @type Boolean
* @default false
*/
draggable : {
validator : Y.Lang.isBoolean,
value : false
},
COUNT: {
value: 0
}
}
});
M.core.dialogue = DIALOGUE;
}, '@VERSION@', {"requires": ["base", "node", "panel", "event-key", "dd-plugin"]});

View File

@ -0,0 +1 @@
YUI.add("moodle-core-notification-dialogue",function(e,t){var n,r,i,s,o,u,a,f;n="moodle-dialogue",r="notificationBase",i=0,s="yesLabel",o="noLabel",u="title",a="question",f={BASE:"moodle-dialogue-base",WRAP:"moodle-dialogue-wrap",HEADER:"moodle-dialogue-hd",BODY:"moodle-dialogue-bd",CONTENT:"moodle-dialogue-content",FOOTER:"moodle-dialogue-ft",HIDDEN:"hidden",LIGHTBOX:"moodle-dialogue-lightbox"},M.core=M.core||{};var l="Moodle dialogue",c;c=function(t){i++;var n="moodle-dialogue-"+i;t.notificationBase=e.Node.create('<div class="'+f.BASE+'">').append(e.Node.create('<div id="'+n+'" role="dialog" aria-labelledby="'+n+'-header-text" class="'+f.WRAP+'"></div>').append(e.Node.create('<div class="'+f.HEADER+' yui3-widget-hd"></div>')).append(e.Node.create('<div class="'+f.BODY+' yui3-widget-bd"></div>')).append(e.Node.create('<div class="'+f.FOOTER+' yui3-widget-ft"></div>'))),e.one(document.body).append(t.notificationBase),t.srcNode="#"+n,t.width=t.width||"400px",t.visible=t.visible||!1,t.center=t.centered||!0,t.centered=!1,t.COUNT=i,t.lightbox!==!1&&(t.modal=!0),delete t.lightbox,t.closeButton===!1?t.buttons=null:t.buttons=[{section:e.WidgetStdMod.HEADER,classNames:"closebutton",action:function(){this.hide()}}],c.superclass.constructor.apply(this,[t]),t.closeButton!==!1&&this.get("buttons").header[0].setAttribute("title",this.get("closeButtonTitle"))},e.extend(c,e.Panel,{initializer:function(){this.after("visibleChange",this.visibilityChanged,this),this.render(),this.show(),this.set("COUNT",i),this.get("boundingBox").setStyle("zIndex",null)},visibilityChanged:function(t){var n;t.attrName==="visible"&&(this.get("maskNode").addClass(f.LIGHTBOX),this.get("center")&&!t.prevVal&&t.newVal&&this.centerDialogue(),this.get("draggable")&&(n="#"+this.get("id")+" ."+f.HEADER,this.plug(e.Plugin.Drag,{handles:[n]}),e.one(n).setStyle("cursor","move")))},centerDialogue:function(){var t=this.get("boundingBox"),r=t.hasClass(n+"-hidden"),i,s;r&&t.setStyle("top","-1000px").removeClass(n+"-hidden"),i=Math.max(Math.round((t.get("winWidth")-t.get("offsetWidth"))/2),15),s=Math.max(Math.round((t.get("winHeight")-t.get("offsetHeight"))/2),15)+e.one(window).get("scrollTop"),r&&t.addClass(n+"-hidden"),t.setStyle("left",i).setStyle("top",s)}},{NAME:l,CSS_PREFIX:n,ATTRS:{notificationBase:{},lightbox:{validator:e.Lang.isBoolean,value:!0},closeButton:{validator:e.Lang.isBoolean,value:!0},closeButtonTitle:{validator:e.Lang.isString,value:"Close"},center:{validator:e.Lang.isBoolean,value:!0},draggable:{validator:e.Lang.isBoolean,value:!1},COUNT:{value:0}}}),M.core.dialogue=c},"@VERSION@",{requires:["base","node","panel","event-key","dd-plugin"]});

View File

@ -0,0 +1,214 @@
YUI.add('moodle-core-notification-dialogue', function (Y, NAME) {
var DIALOGUE_PREFIX,
BASE,
COUNT,
CONFIRMYES,
CONFIRMNO,
TITLE,
QUESTION,
CSS;
DIALOGUE_PREFIX = 'moodle-dialogue',
BASE = 'notificationBase',
COUNT = 0,
CONFIRMYES = 'yesLabel',
CONFIRMNO = 'noLabel',
TITLE = 'title',
QUESTION = 'question',
CSS = {
BASE : 'moodle-dialogue-base',
WRAP : 'moodle-dialogue-wrap',
HEADER : 'moodle-dialogue-hd',
BODY : 'moodle-dialogue-bd',
CONTENT : 'moodle-dialogue-content',
FOOTER : 'moodle-dialogue-ft',
HIDDEN : 'hidden',
LIGHTBOX : 'moodle-dialogue-lightbox'
};
// Set up the namespace once.
M.core = M.core || {};
/**
* The generic dialogue class for use in Moodle.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-dialogue
*/
var DIALOGUE_NAME = 'Moodle dialogue',
DIALOGUE;
/**
* A re-usable dialogue box with Moodle classes applied.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.dialogue
* @extends Y.Panel
*/
DIALOGUE = function(config) {
COUNT++;
var id = 'moodle-dialogue-'+COUNT;
config.notificationBase =
Y.Node.create('<div class="'+CSS.BASE+'">')
.append(Y.Node.create('<div id="'+id+'" role="dialog" aria-labelledby="'+id+'-header-text" class="'+CSS.WRAP+'"></div>')
.append(Y.Node.create('<div class="'+CSS.HEADER+' yui3-widget-hd"></div>'))
.append(Y.Node.create('<div class="'+CSS.BODY+' yui3-widget-bd"></div>'))
.append(Y.Node.create('<div class="'+CSS.FOOTER+' yui3-widget-ft"></div>')));
Y.one(document.body).append(config.notificationBase);
config.srcNode = '#'+id;
config.width = config.width || '400px';
config.visible = config.visible || false;
config.center = config.centered || true;
config.centered = false;
config.COUNT = COUNT;
// lightbox param to keep the stable versions API.
if (config.lightbox !== false) {
config.modal = true;
}
delete config.lightbox;
// closeButton param to keep the stable versions API.
if (config.closeButton === false) {
config.buttons = null;
} else {
config.buttons = [
{
section: Y.WidgetStdMod.HEADER,
classNames: 'closebutton',
action: function () {
this.hide();
}
}
];
}
DIALOGUE.superclass.constructor.apply(this, [config]);
if (config.closeButton !== false) {
// The buttons constructor does not allow custom attributes
this.get('buttons').header[0].setAttribute('title', this.get('closeButtonTitle'));
}
};
Y.extend(DIALOGUE, Y.Panel, {
initializer : function() {
this.after('visibleChange', this.visibilityChanged, this);
this.render();
this.show();
this.set('COUNT', COUNT);
// Workaround upstream YUI bug http://yuilibrary.com/projects/yui3/ticket/2532507
// and allow setting of z-index in theme.
this.get('boundingBox').setStyle('zIndex', null);
},
visibilityChanged : function(e) {
var titlebar;
if (e.attrName === 'visible') {
this.get('maskNode').addClass(CSS.LIGHTBOX);
if (this.get('center') && !e.prevVal && e.newVal) {
this.centerDialogue();
}
if (this.get('draggable')) {
titlebar = '#' + this.get('id') + ' .' + CSS.HEADER;
this.plug(Y.Plugin.Drag, {handles : [titlebar]});
Y.one(titlebar).setStyle('cursor', 'move');
}
}
},
centerDialogue : function() {
var bb = this.get('boundingBox'),
hidden = bb.hasClass(DIALOGUE_PREFIX+'-hidden'),
x, y;
if (hidden) {
bb.setStyle('top', '-1000px').removeClass(DIALOGUE_PREFIX+'-hidden');
}
x = Math.max(Math.round((bb.get('winWidth') - bb.get('offsetWidth'))/2), 15);
y = Math.max(Math.round((bb.get('winHeight') - bb.get('offsetHeight'))/2), 15) + Y.one(window).get('scrollTop');
if (hidden) {
bb.addClass(DIALOGUE_PREFIX+'-hidden');
}
bb.setStyle('left', x).setStyle('top', y);
}
}, {
NAME : DIALOGUE_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
notificationBase : {
},
/**
* Whether to display the dialogue modally and with a
* lightbox style.
*
* @attribute lightbox
* @type Boolean
* @default true
*/
lightbox : {
validator : Y.Lang.isBoolean,
value : true
},
/**
* Whether to display a close button on the dialogue.
*
* Note, we do not recommend hiding the close button as this has
* potential accessibility concerns.
*
* @attribute closeButton
* @type Boolean
* @default true
*/
closeButton : {
validator : Y.Lang.isBoolean,
value : true
},
/**
* The title for the close button if one is to be shown.
*
* @attribute closeButtonTitle
* @type String
* @default 'Close'
*/
closeButtonTitle : {
validator : Y.Lang.isString,
value : 'Close'
},
/**
* Whether to display the dialogue centrally on the screen.
*
* @attribute center
* @type Boolean
* @default true
*/
center : {
validator : Y.Lang.isBoolean,
value : true
},
/**
* Whether to make the dialogue movable around the page.
*
* @attribute draggable
* @type Boolean
* @default false
*/
draggable : {
validator : Y.Lang.isBoolean,
value : false
},
COUNT: {
value: 0
}
}
});
M.core.dialogue = DIALOGUE;
}, '@VERSION@', {"requires": ["base", "node", "panel", "event-key", "dd-plugin"]});

View File

@ -0,0 +1,183 @@
YUI.add('moodle-core-notification-exception', function (Y, NAME) {
var DIALOGUE_PREFIX,
BASE,
COUNT,
CONFIRMYES,
CONFIRMNO,
TITLE,
QUESTION,
CSS;
DIALOGUE_PREFIX = 'moodle-dialogue',
BASE = 'notificationBase',
COUNT = 0,
CONFIRMYES = 'yesLabel',
CONFIRMNO = 'noLabel',
TITLE = 'title',
QUESTION = 'question',
CSS = {
BASE : 'moodle-dialogue-base',
WRAP : 'moodle-dialogue-wrap',
HEADER : 'moodle-dialogue-hd',
BODY : 'moodle-dialogue-bd',
CONTENT : 'moodle-dialogue-content',
FOOTER : 'moodle-dialogue-ft',
HIDDEN : 'hidden',
LIGHTBOX : 'moodle-dialogue-lightbox'
};
// Set up the namespace once.
M.core = M.core || {};
/**
* A dialogue type designed to display an appropriate error when a generic
* javascript error was thrown and caught.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-exception
*/
var EXCEPTION_NAME = 'Moodle exception',
EXCEPTION;
/**
* Extends core Dialogue to show the exception dialogue.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.exception
* @extends M.core.dialogue
*/
EXCEPTION = function(config) {
config.width = config.width || (M.cfg.developerdebug)?Math.floor(Y.one(document.body).get('winWidth')/3)+'px':null;
config.closeButton = true;
EXCEPTION.superclass.constructor.apply(this, [config]);
};
Y.extend(EXCEPTION, M.core.dialogue, {
_hideTimeout : null,
_keypress : null,
initializer : function(config) {
var content,
self = this,
delay = this.get('hideTimeoutDelay');
this.get(BASE).addClass('moodle-dialogue-exception');
this.setStdModContent(Y.WidgetStdMod.HEADER,
'<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + config.name + '</h1>', Y.WidgetStdMod.REPLACE);
content = Y.Node.create('<div class="moodle-exception"></div>')
.append(Y.Node.create('<div class="moodle-exception-message">'+this.get('message')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-filename"><label>File:</label> ' +
this.get('fileName')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-linenumber"><label>Line:</label> ' +
this.get('lineNumber')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>' +
this.get('stack')+'</pre></div>'));
if (M.cfg.developerdebug) {
content.all('.moodle-exception-param').removeClass('hidden');
}
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
if (delay) {
this._hideTimeout = setTimeout(function(){self.hide();}, delay);
}
this.after('visibleChange', this.visibilityChanged, this);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._keypress = Y.on('key', this.hide, window, 'down:13,27', this);
this.centerDialogue();
},
visibilityChanged : function(e) {
if (e.attrName === 'visible' && e.prevVal && !e.newVal) {
if (this._keypress) {
this._keypress.detach();
}
var self = this;
setTimeout(function(){self.destroy();}, 1000);
}
}
}, {
NAME : EXCEPTION_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
/**
* The message of the alert.
*
* @attribute message
* @type String
* @default ''
*/
message : {
value : ''
},
/**
* The name of the alert.
*
* @attribute title
* @type String
* @default ''
*/
name : {
value : ''
},
/**
* The name of the file where the error was thrown.
*
* @attribute fileName
* @type String
* @default ''
*/
fileName : {
value : ''
},
/**
* The line number where the error was thrown.
*
* @attribute lineNumber
* @type String
* @default ''
*/
lineNumber : {
value : ''
},
/**
* The backtrace from the error
*
* @attribute lineNumber
* @type String
* @default ''
*/
stack : {
setter : function(str) {
var lines = str.split("\n"),
pattern = new RegExp('^(.+)@('+M.cfg.wwwroot+')?(.{0,75}).*:(\\d+)$'),
i;
for (i in lines) {
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>");
}
return lines.join('');
},
value : ''
},
/**
* If set, the dialogue is hidden after the specified timeout period.
*
* @attribute hideTimeoutDelay
* @type Number
* @default null
* @optional
*/
hideTimeoutDelay : {
validator : Y.Lang.isNumber,
value : null
}
}
});
M.core.exception = EXCEPTION;
}, '@VERSION@', {"requires": ["moodle-core-notification-dialogue"]});

View File

@ -0,0 +1 @@
YUI.add("moodle-core-notification-exception",function(e,t){var n,r,i,s,o,u,a,f;n="moodle-dialogue",r="notificationBase",i=0,s="yesLabel",o="noLabel",u="title",a="question",f={BASE:"moodle-dialogue-base",WRAP:"moodle-dialogue-wrap",HEADER:"moodle-dialogue-hd",BODY:"moodle-dialogue-bd",CONTENT:"moodle-dialogue-content",FOOTER:"moodle-dialogue-ft",HIDDEN:"hidden",LIGHTBOX:"moodle-dialogue-lightbox"},M.core=M.core||{};var l="Moodle exception",c;c=function(t){t.width=t.width||M.cfg.developerdebug?Math.floor(e.one(document.body).get("winWidth")/3)+"px":null,t.closeButton=!0,c.superclass.constructor.apply(this,[t])},e.extend(c,M.core.dialogue,{_hideTimeout:null,_keypress:null,initializer:function(t){var n,s=this,o=this.get("hideTimeoutDelay");this.get(r).addClass("moodle-dialogue-exception"),this.setStdModContent(e.WidgetStdMod.HEADER,'<h1 id="moodle-dialogue-'+i+'-header-text">'+t.name+"</h1>",e.WidgetStdMod.REPLACE),n=e.Node.create('<div class="moodle-exception"></div>').append(e.Node.create('<div class="moodle-exception-message">'+this.get("message")+"</div>")).append(e.Node.create('<div class="moodle-exception-param hidden param-filename"><label>File:</label> '+this.get("fileName")+"</div>")).append(e.Node.create('<div class="moodle-exception-param hidden param-linenumber"><label>Line:</label> '+this.get("lineNumber")+"</div>")).append(e.Node.create('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>'+this.get("stack")+"</pre></div>")),M.cfg.developerdebug&&n.all(".moodle-exception-param").removeClass("hidden"),this.setStdModContent(e.WidgetStdMod.BODY,n,e.WidgetStdMod.REPLACE),o&&(this._hideTimeout=setTimeout(function(){s.hide()},o)),this.after("visibleChange",this.visibilityChanged,this),this.after("destroyedChange",function(){this.get(r).remove()},this),this._keypress=e.on("key",this.hide,window,"down:13,27",this),this.centerDialogue()},visibilityChanged:function(e){if(e.attrName==="visible"&&e.prevVal&&!e.newVal){this._keypress&&this._keypress.detach();var t=this;setTimeout(function(){t.destroy()},1e3)}}},{NAME:l,CSS_PREFIX:n,ATTRS:{message:{value:""},name:{value:""},fileName:{value:""},lineNumber:{value:""},stack:{setter:function(e){var t=e.split("\n"),n=new RegExp("^(.+)@("+M.cfg.wwwroot+")?(.{0,75}).*:(\\d+)$"),r;for(r in t)t[r]=t[r].replace(n,"<div class='stacktrace-line'>ln: $4</div><div class='stacktrace-file'>$3</div><div class='stacktrace-call'>$1</div>");return t.join("")},value:""},hideTimeoutDelay:{validator:e.Lang.isNumber,value:null}}}),M.core.exception=c},"@VERSION@",{requires:["moodle-core-notification-dialogue"]});

View File

@ -0,0 +1,183 @@
YUI.add('moodle-core-notification-exception', function (Y, NAME) {
var DIALOGUE_PREFIX,
BASE,
COUNT,
CONFIRMYES,
CONFIRMNO,
TITLE,
QUESTION,
CSS;
DIALOGUE_PREFIX = 'moodle-dialogue',
BASE = 'notificationBase',
COUNT = 0,
CONFIRMYES = 'yesLabel',
CONFIRMNO = 'noLabel',
TITLE = 'title',
QUESTION = 'question',
CSS = {
BASE : 'moodle-dialogue-base',
WRAP : 'moodle-dialogue-wrap',
HEADER : 'moodle-dialogue-hd',
BODY : 'moodle-dialogue-bd',
CONTENT : 'moodle-dialogue-content',
FOOTER : 'moodle-dialogue-ft',
HIDDEN : 'hidden',
LIGHTBOX : 'moodle-dialogue-lightbox'
};
// Set up the namespace once.
M.core = M.core || {};
/**
* A dialogue type designed to display an appropriate error when a generic
* javascript error was thrown and caught.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-exception
*/
var EXCEPTION_NAME = 'Moodle exception',
EXCEPTION;
/**
* Extends core Dialogue to show the exception dialogue.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.exception
* @extends M.core.dialogue
*/
EXCEPTION = function(config) {
config.width = config.width || (M.cfg.developerdebug)?Math.floor(Y.one(document.body).get('winWidth')/3)+'px':null;
config.closeButton = true;
EXCEPTION.superclass.constructor.apply(this, [config]);
};
Y.extend(EXCEPTION, M.core.dialogue, {
_hideTimeout : null,
_keypress : null,
initializer : function(config) {
var content,
self = this,
delay = this.get('hideTimeoutDelay');
this.get(BASE).addClass('moodle-dialogue-exception');
this.setStdModContent(Y.WidgetStdMod.HEADER,
'<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + config.name + '</h1>', Y.WidgetStdMod.REPLACE);
content = Y.Node.create('<div class="moodle-exception"></div>')
.append(Y.Node.create('<div class="moodle-exception-message">'+this.get('message')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-filename"><label>File:</label> ' +
this.get('fileName')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-linenumber"><label>Line:</label> ' +
this.get('lineNumber')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>' +
this.get('stack')+'</pre></div>'));
if (M.cfg.developerdebug) {
content.all('.moodle-exception-param').removeClass('hidden');
}
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
if (delay) {
this._hideTimeout = setTimeout(function(){self.hide();}, delay);
}
this.after('visibleChange', this.visibilityChanged, this);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._keypress = Y.on('key', this.hide, window, 'down:13,27', this);
this.centerDialogue();
},
visibilityChanged : function(e) {
if (e.attrName === 'visible' && e.prevVal && !e.newVal) {
if (this._keypress) {
this._keypress.detach();
}
var self = this;
setTimeout(function(){self.destroy();}, 1000);
}
}
}, {
NAME : EXCEPTION_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
/**
* The message of the alert.
*
* @attribute message
* @type String
* @default ''
*/
message : {
value : ''
},
/**
* The name of the alert.
*
* @attribute title
* @type String
* @default ''
*/
name : {
value : ''
},
/**
* The name of the file where the error was thrown.
*
* @attribute fileName
* @type String
* @default ''
*/
fileName : {
value : ''
},
/**
* The line number where the error was thrown.
*
* @attribute lineNumber
* @type String
* @default ''
*/
lineNumber : {
value : ''
},
/**
* The backtrace from the error
*
* @attribute lineNumber
* @type String
* @default ''
*/
stack : {
setter : function(str) {
var lines = str.split("\n"),
pattern = new RegExp('^(.+)@('+M.cfg.wwwroot+')?(.{0,75}).*:(\\d+)$'),
i;
for (i in lines) {
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>");
}
return lines.join('');
},
value : ''
},
/**
* If set, the dialogue is hidden after the specified timeout period.
*
* @attribute hideTimeoutDelay
* @type Number
* @default null
* @optional
*/
hideTimeoutDelay : {
validator : Y.Lang.isNumber,
value : null
}
}
});
M.core.exception = EXCEPTION;
}, '@VERSION@', {"requires": ["moodle-core-notification-dialogue"]});

View File

@ -1,408 +1,38 @@
YUI.add('moodle-core-notification', function (Y, NAME) { YUI.add('moodle-core-notification', function (Y, NAME) {
var DIALOGUE_NAME = 'Moodle dialogue', /**
DIALOGUE_PREFIX = 'moodle-dialogue', * The notification module provides a standard set of dialogues for use
CONFIRM_NAME = 'Moodle confirmation dialogue', * within Moodle.
EXCEPTION_NAME = 'Moodle exception', *
AJAXEXCEPTION_NAME = 'Moodle AJAX exception', * @module moodle-core-notification
ALERT_NAME = 'Moodle alert', * @main
BASE = 'notificationBase', */
COUNT = 0,
CONFIRMYES = 'yesLabel',
CONFIRMNO = 'noLabel',
TITLE = 'title',
QUESTION = 'question',
CSS = {
BASE : 'moodle-dialogue-base',
WRAP : 'moodle-dialogue-wrap',
HEADER : 'moodle-dialogue-hd',
BODY : 'moodle-dialogue-bd',
CONTENT : 'moodle-dialogue-content',
FOOTER : 'moodle-dialogue-ft',
HIDDEN : 'hidden',
LIGHTBOX : 'moodle-dialogue-lightbox'
},
EXCEPTION,
ALERT,
CONFIRM,
AJAXEXCEPTION,
DIALOGUE;
DIALOGUE = function(config) { /**
COUNT++; * To avoid bringing moodle-core-notification into modules in it's
var id = 'moodle-dialogue-'+COUNT; * entirety, we now recommend using on of the subclasses of
config.notificationBase = * moodle-core-notification. These include:
Y.Node.create('<div class="'+CSS.BASE+'">') * <dl>
.append(Y.Node.create('<div id="'+id+'" role="dialog" aria-labelledby="'+id+'-header-text" class="'+CSS.WRAP+'"></div>') * <dt> moodle-core-notification-dialogue</dt>
.append(Y.Node.create('<div class="'+CSS.HEADER+' yui3-widget-hd"></div>')) * <dt> moodle-core-notification-alert</dt>
.append(Y.Node.create('<div class="'+CSS.BODY+' yui3-widget-bd"></div>')) * <dt> moodle-core-notification-confirm</dt>
.append(Y.Node.create('<div class="'+CSS.FOOTER+' yui3-widget-ft"></div>'))); * <dt> moodle-core-notification-exception</dt>
Y.one(document.body).append(config.notificationBase); * <dt> moodle-core-notification-ajaxexception</dt>
config.srcNode = '#'+id; * </dl>
config.width = config.width || '400px'; *
config.visible = config.visible || false; * @class M.core.notification
config.center = config.centered || true; * @deprecated
config.centered = false; */
Y.log("The moodle-core-notification parent module has been deprecated. " +
"Please use one of its' subclasses instead.", 'moodle-core-notification', 'warn');
// lightbox param to keep the stable versions API.
if (config.lightbox !== false) {
config.modal = true;
}
delete config.lightbox;
// closeButton param to keep the stable versions API. }, '@VERSION@', {
if (config.closeButton === false) { "requires": [
config.buttons = null; "moodle-core-notification-dialogue",
} else { "moodle-core-notification-alert",
config.buttons = [ "moodle-core-notification-confirm",
{ "moodle-core-notification-exception",
section: Y.WidgetStdMod.HEADER, "moodle-core-notification-ajaxexception"
classNames: 'closebutton', ]
action: function () {
this.hide();
}
}
];
}
DIALOGUE.superclass.constructor.apply(this, [config]);
if (config.closeButton !== false) {
// The buttons constructor does not allow custom attributes
this.get('buttons').header[0].setAttribute('title', this.get('closeButtonTitle'));
}
};
Y.extend(DIALOGUE, Y.Panel, {
initializer : function() {
this.after('visibleChange', this.visibilityChanged, this);
this.render();
this.show();
// Workaround upstream YUI bug http://yuilibrary.com/projects/yui3/ticket/2532507
// and allow setting of z-index in theme.
this.get('boundingBox').setStyle('zIndex', null);
},
visibilityChanged : function(e) {
var titlebar;
if (e.attrName === 'visible') {
this.get('maskNode').addClass(CSS.LIGHTBOX);
if (this.get('center') && !e.prevVal && e.newVal) {
this.centerDialogue();
}
if (this.get('draggable')) {
titlebar = '#' + this.get('id') + ' .' + CSS.HEADER;
this.plug(Y.Plugin.Drag, {handles : [titlebar]});
Y.one(titlebar).setStyle('cursor', 'move');
}
}
},
centerDialogue : function() {
var bb = this.get('boundingBox'),
hidden = bb.hasClass(DIALOGUE_PREFIX+'-hidden'),
x, y;
if (hidden) {
bb.setStyle('top', '-1000px').removeClass(DIALOGUE_PREFIX+'-hidden');
}
x = Math.max(Math.round((bb.get('winWidth') - bb.get('offsetWidth'))/2), 15);
y = Math.max(Math.round((bb.get('winHeight') - bb.get('offsetHeight'))/2), 15) + Y.one(window).get('scrollTop');
if (hidden) {
bb.addClass(DIALOGUE_PREFIX+'-hidden');
}
bb.setStyle('left', x).setStyle('top', y);
}
}, {
NAME : DIALOGUE_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
notificationBase : {
},
lightbox : {
validator : Y.Lang.isBoolean,
value : true
},
closeButton : {
validator : Y.Lang.isBoolean,
value : true
},
closeButtonTitle : {
validator : Y.Lang.isString,
value : 'Close'
},
center : {
validator : Y.Lang.isBoolean,
value : true
},
draggable : {
validator : Y.Lang.isBoolean,
value : false
}
}
}); });
ALERT = function(config) {
config.closeButton = false;
ALERT.superclass.constructor.apply(this, [config]);
};
Y.extend(ALERT, DIALOGUE, {
_enterKeypress : null,
initializer : function() {
this.publish('complete');
var yes = Y.Node.create('<input type="button" id="id_yuialertconfirm-' + this.COUNT + '" value="'+this.get(CONFIRMYES)+'" />'),
content = Y.Node.create('<div class="confirmation-dialogue"></div>')
.append(Y.Node.create('<div class="confirmation-message">'+this.get('message')+'</div>'))
.append(Y.Node.create('<div class="confirmation-buttons"></div>')
.append(yes));
this.get(BASE).addClass('moodle-dialogue-confirm');
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
this.setStdModContent(Y.WidgetStdMod.HEADER, '<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + this.get(TITLE) + '</h1>', Y.WidgetStdMod.REPLACE);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._enterKeypress = Y.on('key', this.submit, window, 'down:13', this);
yes.on('click', this.submit, this);
},
submit : function() {
this._enterKeypress.detach();
this.fire('complete');
this.hide();
this.destroy();
}
}, {
NAME : ALERT_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
title : {
validator : Y.Lang.isString,
value : 'Alert'
},
message : {
validator : Y.Lang.isString,
value : 'Confirm'
},
yesLabel : {
validator : Y.Lang.isString,
setter : function(txt) {
if (!txt) {
txt = 'Ok';
}
return txt;
},
value : 'Ok'
}
}
});
CONFIRM = function(config) {
CONFIRM.superclass.constructor.apply(this, [config]);
};
Y.extend(CONFIRM, DIALOGUE, {
_enterKeypress : null,
_escKeypress : null,
initializer : function() {
this.publish('complete');
this.publish('complete-yes');
this.publish('complete-no');
var yes = Y.Node.create('<input type="button" id="id_yuiconfirmyes-' + this.COUNT + '" value="'+this.get(CONFIRMYES)+'" />'),
no = Y.Node.create('<input type="button" id="id_yuiconfirmno-' + this.COUNT + '" value="'+this.get(CONFIRMNO)+'" />'),
content = Y.Node.create('<div class="confirmation-dialogue"></div>')
.append(Y.Node.create('<div class="confirmation-message">'+this.get(QUESTION)+'</div>'))
.append(Y.Node.create('<div class="confirmation-buttons"></div>')
.append(yes)
.append(no));
this.get(BASE).addClass('moodle-dialogue-confirm');
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
this.setStdModContent(Y.WidgetStdMod.HEADER, '<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + this.get(TITLE) + '</h1>', Y.WidgetStdMod.REPLACE);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._enterKeypress = Y.on('key', this.submit, window, 'down:13', this, true);
this._escKeypress = Y.on('key', this.submit, window, 'down:27', this, false);
yes.on('click', this.submit, this, true);
no.on('click', this.submit, this, false);
},
submit : function(e, outcome) {
this._enterKeypress.detach();
this._escKeypress.detach();
this.fire('complete', outcome);
if (outcome) {
this.fire('complete-yes');
} else {
this.fire('complete-no');
}
this.hide();
this.destroy();
}
}, {
NAME : CONFIRM_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
yesLabel : {
validator : Y.Lang.isString,
value : 'Yes'
},
noLabel : {
validator : Y.Lang.isString,
value : 'No'
},
title : {
validator : Y.Lang.isString,
value : 'Confirm'
},
question : {
validator : Y.Lang.isString,
value : 'Are you sure?'
}
}
});
Y.augment(CONFIRM, Y.EventTarget);
EXCEPTION = function(config) {
config.width = config.width || (M.cfg.developerdebug)?Math.floor(Y.one(document.body).get('winWidth')/3)+'px':null;
config.closeButton = true;
EXCEPTION.superclass.constructor.apply(this, [config]);
};
Y.extend(EXCEPTION, DIALOGUE, {
_hideTimeout : null,
_keypress : null,
initializer : function(config) {
var content,
self = this,
delay = this.get('hideTimeoutDelay');
this.get(BASE).addClass('moodle-dialogue-exception');
this.setStdModContent(Y.WidgetStdMod.HEADER, '<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + config.name + '</h1>', Y.WidgetStdMod.REPLACE);
content = Y.Node.create('<div class="moodle-exception"></div>')
.append(Y.Node.create('<div class="moodle-exception-message">'+this.get('message')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-filename"><label>File:</label> '+this.get('fileName')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-linenumber"><label>Line:</label> '+this.get('lineNumber')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>'+this.get('stack')+'</pre></div>'));
if (M.cfg.developerdebug) {
content.all('.moodle-exception-param').removeClass('hidden');
}
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
if (delay) {
this._hideTimeout = setTimeout(function(){self.hide();}, delay);
}
this.after('visibleChange', this.visibilityChanged, this);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._keypress = Y.on('key', this.hide, window, 'down:13,27', this);
this.centerDialogue();
},
visibilityChanged : function(e) {
if (e.attrName === 'visible' && e.prevVal && !e.newVal) {
if (this._keypress) {
this._keypress.detach();
}
var self = this;
setTimeout(function(){self.destroy();}, 1000);
}
}
}, {
NAME : EXCEPTION_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
message : {
value : ''
},
name : {
value : ''
},
fileName : {
value : ''
},
lineNumber : {
value : ''
},
stack : {
setter : function(str) {
var lines = str.split("\n"),
pattern = new RegExp('^(.+)@('+M.cfg.wwwroot+')?(.{0,75}).*:(\\d+)$'),
i;
for (i in lines) {
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>");
}
return lines.join('');
},
value : ''
},
hideTimeoutDelay : {
validator : Y.Lang.isNumber,
value : null
}
}
});
AJAXEXCEPTION = function(config) {
config.name = config.name || 'Error';
config.closeButton = true;
AJAXEXCEPTION.superclass.constructor.apply(this, [config]);
};
Y.extend(AJAXEXCEPTION, DIALOGUE, {
_keypress : null,
initializer : function(config) {
var content,
self = this,
delay = this.get('hideTimeoutDelay');
this.get(BASE).addClass('moodle-dialogue-exception');
this.setStdModContent(Y.WidgetStdMod.HEADER, '<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + config.name + '</h1>', Y.WidgetStdMod.REPLACE);
content = Y.Node.create('<div class="moodle-ajaxexception"></div>')
.append(Y.Node.create('<div class="moodle-exception-message">'+this.get('error')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-debuginfo"><label>URL:</label> '+this.get('reproductionlink')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-debuginfo"><label>Debug info:</label> '+this.get('debuginfo')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>'+this.get('stacktrace')+'</pre></div>'));
if (M.cfg.developerdebug) {
content.all('.moodle-exception-param').removeClass('hidden');
}
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
if (delay) {
this._hideTimeout = setTimeout(function(){self.hide();}, delay);
}
this.after('visibleChange', this.visibilityChanged, this);
this._keypress = Y.on('key', this.hide, window, 'down:13, 27', this);
this.centerDialogue();
},
visibilityChanged : function(e) {
if (e.attrName === 'visible' && e.prevVal && !e.newVal) {
var self = this;
this._keypress.detach();
setTimeout(function(){self.destroy();}, 1000);
}
}
}, {
NAME : AJAXEXCEPTION_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
error : {
validator : Y.Lang.isString,
value : 'Unknown error'
},
debuginfo : {
value : null
},
stacktrace : {
value : null
},
reproductionlink : {
setter : function(link) {
if (link !== null) {
link = '<a href="'+link+'">'+link.replace(M.cfg.wwwroot, '')+'</a>';
}
return link;
},
value : null
},
hideTimeoutDelay : {
validator : Y.Lang.isNumber,
value : null
}
}
});
M.core = M.core || {};
M.core.dialogue = DIALOGUE;
M.core.alert = ALERT;
M.core.confirm = CONFIRM;
M.core.exception = EXCEPTION;
M.core.ajaxException = AJAXEXCEPTION;
}, '@VERSION@', {"requires": ["base", "node", "panel", "event-key", "dd-plugin"]});

File diff suppressed because one or more lines are too long

View File

@ -1,408 +1,36 @@
YUI.add('moodle-core-notification', function (Y, NAME) { YUI.add('moodle-core-notification', function (Y, NAME) {
var DIALOGUE_NAME = 'Moodle dialogue', /**
DIALOGUE_PREFIX = 'moodle-dialogue', * The notification module provides a standard set of dialogues for use
CONFIRM_NAME = 'Moodle confirmation dialogue', * within Moodle.
EXCEPTION_NAME = 'Moodle exception', *
AJAXEXCEPTION_NAME = 'Moodle AJAX exception', * @module moodle-core-notification
ALERT_NAME = 'Moodle alert', * @main
BASE = 'notificationBase', */
COUNT = 0,
CONFIRMYES = 'yesLabel',
CONFIRMNO = 'noLabel',
TITLE = 'title',
QUESTION = 'question',
CSS = {
BASE : 'moodle-dialogue-base',
WRAP : 'moodle-dialogue-wrap',
HEADER : 'moodle-dialogue-hd',
BODY : 'moodle-dialogue-bd',
CONTENT : 'moodle-dialogue-content',
FOOTER : 'moodle-dialogue-ft',
HIDDEN : 'hidden',
LIGHTBOX : 'moodle-dialogue-lightbox'
},
EXCEPTION,
ALERT,
CONFIRM,
AJAXEXCEPTION,
DIALOGUE;
DIALOGUE = function(config) { /**
COUNT++; * To avoid bringing moodle-core-notification into modules in it's
var id = 'moodle-dialogue-'+COUNT; * entirety, we now recommend using on of the subclasses of
config.notificationBase = * moodle-core-notification. These include:
Y.Node.create('<div class="'+CSS.BASE+'">') * <dl>
.append(Y.Node.create('<div id="'+id+'" role="dialog" aria-labelledby="'+id+'-header-text" class="'+CSS.WRAP+'"></div>') * <dt> moodle-core-notification-dialogue</dt>
.append(Y.Node.create('<div class="'+CSS.HEADER+' yui3-widget-hd"></div>')) * <dt> moodle-core-notification-alert</dt>
.append(Y.Node.create('<div class="'+CSS.BODY+' yui3-widget-bd"></div>')) * <dt> moodle-core-notification-confirm</dt>
.append(Y.Node.create('<div class="'+CSS.FOOTER+' yui3-widget-ft"></div>'))); * <dt> moodle-core-notification-exception</dt>
Y.one(document.body).append(config.notificationBase); * <dt> moodle-core-notification-ajaxexception</dt>
config.srcNode = '#'+id; * </dl>
config.width = config.width || '400px'; *
config.visible = config.visible || false; * @class M.core.notification
config.center = config.centered || true; * @deprecated
config.centered = false; */
// lightbox param to keep the stable versions API.
if (config.lightbox !== false) {
config.modal = true;
}
delete config.lightbox;
// closeButton param to keep the stable versions API. }, '@VERSION@', {
if (config.closeButton === false) { "requires": [
config.buttons = null; "moodle-core-notification-dialogue",
} else { "moodle-core-notification-alert",
config.buttons = [ "moodle-core-notification-confirm",
{ "moodle-core-notification-exception",
section: Y.WidgetStdMod.HEADER, "moodle-core-notification-ajaxexception"
classNames: 'closebutton', ]
action: function () {
this.hide();
}
}
];
}
DIALOGUE.superclass.constructor.apply(this, [config]);
if (config.closeButton !== false) {
// The buttons constructor does not allow custom attributes
this.get('buttons').header[0].setAttribute('title', this.get('closeButtonTitle'));
}
};
Y.extend(DIALOGUE, Y.Panel, {
initializer : function() {
this.after('visibleChange', this.visibilityChanged, this);
this.render();
this.show();
// Workaround upstream YUI bug http://yuilibrary.com/projects/yui3/ticket/2532507
// and allow setting of z-index in theme.
this.get('boundingBox').setStyle('zIndex', null);
},
visibilityChanged : function(e) {
var titlebar;
if (e.attrName === 'visible') {
this.get('maskNode').addClass(CSS.LIGHTBOX);
if (this.get('center') && !e.prevVal && e.newVal) {
this.centerDialogue();
}
if (this.get('draggable')) {
titlebar = '#' + this.get('id') + ' .' + CSS.HEADER;
this.plug(Y.Plugin.Drag, {handles : [titlebar]});
Y.one(titlebar).setStyle('cursor', 'move');
}
}
},
centerDialogue : function() {
var bb = this.get('boundingBox'),
hidden = bb.hasClass(DIALOGUE_PREFIX+'-hidden'),
x, y;
if (hidden) {
bb.setStyle('top', '-1000px').removeClass(DIALOGUE_PREFIX+'-hidden');
}
x = Math.max(Math.round((bb.get('winWidth') - bb.get('offsetWidth'))/2), 15);
y = Math.max(Math.round((bb.get('winHeight') - bb.get('offsetHeight'))/2), 15) + Y.one(window).get('scrollTop');
if (hidden) {
bb.addClass(DIALOGUE_PREFIX+'-hidden');
}
bb.setStyle('left', x).setStyle('top', y);
}
}, {
NAME : DIALOGUE_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
notificationBase : {
},
lightbox : {
validator : Y.Lang.isBoolean,
value : true
},
closeButton : {
validator : Y.Lang.isBoolean,
value : true
},
closeButtonTitle : {
validator : Y.Lang.isString,
value : 'Close'
},
center : {
validator : Y.Lang.isBoolean,
value : true
},
draggable : {
validator : Y.Lang.isBoolean,
value : false
}
}
}); });
ALERT = function(config) {
config.closeButton = false;
ALERT.superclass.constructor.apply(this, [config]);
};
Y.extend(ALERT, DIALOGUE, {
_enterKeypress : null,
initializer : function() {
this.publish('complete');
var yes = Y.Node.create('<input type="button" id="id_yuialertconfirm-' + this.COUNT + '" value="'+this.get(CONFIRMYES)+'" />'),
content = Y.Node.create('<div class="confirmation-dialogue"></div>')
.append(Y.Node.create('<div class="confirmation-message">'+this.get('message')+'</div>'))
.append(Y.Node.create('<div class="confirmation-buttons"></div>')
.append(yes));
this.get(BASE).addClass('moodle-dialogue-confirm');
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
this.setStdModContent(Y.WidgetStdMod.HEADER, '<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + this.get(TITLE) + '</h1>', Y.WidgetStdMod.REPLACE);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._enterKeypress = Y.on('key', this.submit, window, 'down:13', this);
yes.on('click', this.submit, this);
},
submit : function() {
this._enterKeypress.detach();
this.fire('complete');
this.hide();
this.destroy();
}
}, {
NAME : ALERT_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
title : {
validator : Y.Lang.isString,
value : 'Alert'
},
message : {
validator : Y.Lang.isString,
value : 'Confirm'
},
yesLabel : {
validator : Y.Lang.isString,
setter : function(txt) {
if (!txt) {
txt = 'Ok';
}
return txt;
},
value : 'Ok'
}
}
});
CONFIRM = function(config) {
CONFIRM.superclass.constructor.apply(this, [config]);
};
Y.extend(CONFIRM, DIALOGUE, {
_enterKeypress : null,
_escKeypress : null,
initializer : function() {
this.publish('complete');
this.publish('complete-yes');
this.publish('complete-no');
var yes = Y.Node.create('<input type="button" id="id_yuiconfirmyes-' + this.COUNT + '" value="'+this.get(CONFIRMYES)+'" />'),
no = Y.Node.create('<input type="button" id="id_yuiconfirmno-' + this.COUNT + '" value="'+this.get(CONFIRMNO)+'" />'),
content = Y.Node.create('<div class="confirmation-dialogue"></div>')
.append(Y.Node.create('<div class="confirmation-message">'+this.get(QUESTION)+'</div>'))
.append(Y.Node.create('<div class="confirmation-buttons"></div>')
.append(yes)
.append(no));
this.get(BASE).addClass('moodle-dialogue-confirm');
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
this.setStdModContent(Y.WidgetStdMod.HEADER, '<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + this.get(TITLE) + '</h1>', Y.WidgetStdMod.REPLACE);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._enterKeypress = Y.on('key', this.submit, window, 'down:13', this, true);
this._escKeypress = Y.on('key', this.submit, window, 'down:27', this, false);
yes.on('click', this.submit, this, true);
no.on('click', this.submit, this, false);
},
submit : function(e, outcome) {
this._enterKeypress.detach();
this._escKeypress.detach();
this.fire('complete', outcome);
if (outcome) {
this.fire('complete-yes');
} else {
this.fire('complete-no');
}
this.hide();
this.destroy();
}
}, {
NAME : CONFIRM_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
yesLabel : {
validator : Y.Lang.isString,
value : 'Yes'
},
noLabel : {
validator : Y.Lang.isString,
value : 'No'
},
title : {
validator : Y.Lang.isString,
value : 'Confirm'
},
question : {
validator : Y.Lang.isString,
value : 'Are you sure?'
}
}
});
Y.augment(CONFIRM, Y.EventTarget);
EXCEPTION = function(config) {
config.width = config.width || (M.cfg.developerdebug)?Math.floor(Y.one(document.body).get('winWidth')/3)+'px':null;
config.closeButton = true;
EXCEPTION.superclass.constructor.apply(this, [config]);
};
Y.extend(EXCEPTION, DIALOGUE, {
_hideTimeout : null,
_keypress : null,
initializer : function(config) {
var content,
self = this,
delay = this.get('hideTimeoutDelay');
this.get(BASE).addClass('moodle-dialogue-exception');
this.setStdModContent(Y.WidgetStdMod.HEADER, '<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + config.name + '</h1>', Y.WidgetStdMod.REPLACE);
content = Y.Node.create('<div class="moodle-exception"></div>')
.append(Y.Node.create('<div class="moodle-exception-message">'+this.get('message')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-filename"><label>File:</label> '+this.get('fileName')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-linenumber"><label>Line:</label> '+this.get('lineNumber')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>'+this.get('stack')+'</pre></div>'));
if (M.cfg.developerdebug) {
content.all('.moodle-exception-param').removeClass('hidden');
}
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
if (delay) {
this._hideTimeout = setTimeout(function(){self.hide();}, delay);
}
this.after('visibleChange', this.visibilityChanged, this);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._keypress = Y.on('key', this.hide, window, 'down:13,27', this);
this.centerDialogue();
},
visibilityChanged : function(e) {
if (e.attrName === 'visible' && e.prevVal && !e.newVal) {
if (this._keypress) {
this._keypress.detach();
}
var self = this;
setTimeout(function(){self.destroy();}, 1000);
}
}
}, {
NAME : EXCEPTION_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
message : {
value : ''
},
name : {
value : ''
},
fileName : {
value : ''
},
lineNumber : {
value : ''
},
stack : {
setter : function(str) {
var lines = str.split("\n"),
pattern = new RegExp('^(.+)@('+M.cfg.wwwroot+')?(.{0,75}).*:(\\d+)$'),
i;
for (i in lines) {
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>");
}
return lines.join('');
},
value : ''
},
hideTimeoutDelay : {
validator : Y.Lang.isNumber,
value : null
}
}
});
AJAXEXCEPTION = function(config) {
config.name = config.name || 'Error';
config.closeButton = true;
AJAXEXCEPTION.superclass.constructor.apply(this, [config]);
};
Y.extend(AJAXEXCEPTION, DIALOGUE, {
_keypress : null,
initializer : function(config) {
var content,
self = this,
delay = this.get('hideTimeoutDelay');
this.get(BASE).addClass('moodle-dialogue-exception');
this.setStdModContent(Y.WidgetStdMod.HEADER, '<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + config.name + '</h1>', Y.WidgetStdMod.REPLACE);
content = Y.Node.create('<div class="moodle-ajaxexception"></div>')
.append(Y.Node.create('<div class="moodle-exception-message">'+this.get('error')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-debuginfo"><label>URL:</label> '+this.get('reproductionlink')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-debuginfo"><label>Debug info:</label> '+this.get('debuginfo')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>'+this.get('stacktrace')+'</pre></div>'));
if (M.cfg.developerdebug) {
content.all('.moodle-exception-param').removeClass('hidden');
}
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
if (delay) {
this._hideTimeout = setTimeout(function(){self.hide();}, delay);
}
this.after('visibleChange', this.visibilityChanged, this);
this._keypress = Y.on('key', this.hide, window, 'down:13, 27', this);
this.centerDialogue();
},
visibilityChanged : function(e) {
if (e.attrName === 'visible' && e.prevVal && !e.newVal) {
var self = this;
this._keypress.detach();
setTimeout(function(){self.destroy();}, 1000);
}
}
}, {
NAME : AJAXEXCEPTION_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
error : {
validator : Y.Lang.isString,
value : 'Unknown error'
},
debuginfo : {
value : null
},
stacktrace : {
value : null
},
reproductionlink : {
setter : function(link) {
if (link !== null) {
link = '<a href="'+link+'">'+link.replace(M.cfg.wwwroot, '')+'</a>';
}
return link;
},
value : null
},
hideTimeoutDelay : {
validator : Y.Lang.isNumber,
value : null
}
}
});
M.core = M.core || {};
M.core.dialogue = DIALOGUE;
M.core.alert = ALERT;
M.core.confirm = CONFIRM;
M.core.exception = EXCEPTION;
M.core.ajaxException = AJAXEXCEPTION;
}, '@VERSION@', {"requires": ["base", "node", "panel", "event-key", "dd-plugin"]});

View File

@ -5,6 +5,36 @@
"jsfiles": [ "jsfiles": [
"notification.js" "notification.js"
] ]
},
"moodle-core-notification-dialogue": {
"jsfiles": [
"shared.js",
"dialogue.js"
]
},
"moodle-core-notification-alert": {
"jsfiles": [
"shared.js",
"alert.js"
]
},
"moodle-core-notification-confirm": {
"jsfiles": [
"shared.js",
"confirm.js"
]
},
"moodle-core-notification-exception": {
"jsfiles": [
"shared.js",
"exception.js"
]
},
"moodle-core-notification-ajaxexception": {
"jsfiles": [
"shared.js",
"ajaxexception.js"
]
} }
} }
} }

View File

@ -0,0 +1,136 @@
/**
* A dialogue type designed to display an appropriate error when an error
* thrown in the Moodle codebase was reported during an AJAX request.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-ajaxexception
*/
var AJAXEXCEPTION_NAME = 'Moodle AJAX exception',
AJAXEXCEPTION;
/**
* Extends core Dialogue to show the exception dialogue.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.ajaxException
* @extends M.core.dialogue
*/
AJAXEXCEPTION = function(config) {
config.name = config.name || 'Error';
config.closeButton = true;
AJAXEXCEPTION.superclass.constructor.apply(this, [config]);
};
Y.extend(AJAXEXCEPTION, M.core.dialogue, {
_keypress : null,
initializer : function(config) {
var content,
self = this,
delay = this.get('hideTimeoutDelay');
this.get(BASE).addClass('moodle-dialogue-exception');
this.setStdModContent(Y.WidgetStdMod.HEADER,
'<h1 id="moodle-dialogue-'+this.get('COUNT')+'-header-text">' + config.name + '</h1>', Y.WidgetStdMod.REPLACE);
content = Y.Node.create('<div class="moodle-ajaxexception"></div>')
.append(Y.Node.create('<div class="moodle-exception-message">'+this.get('error')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-debuginfo"><label>URL:</label> ' +
this.get('reproductionlink')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-debuginfo"><label>Debug info:</label> ' +
this.get('debuginfo')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>' +
this.get('stacktrace')+'</pre></div>'));
if (M.cfg.developerdebug) {
content.all('.moodle-exception-param').removeClass('hidden');
}
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
if (delay) {
this._hideTimeout = setTimeout(function(){self.hide();}, delay);
}
this.after('visibleChange', this.visibilityChanged, this);
this._keypress = Y.on('key', this.hide, window, 'down:13, 27', this);
this.centerDialogue();
},
visibilityChanged : function(e) {
if (e.attrName === 'visible' && e.prevVal && !e.newVal) {
var self = this;
this._keypress.detach();
setTimeout(function(){self.destroy();}, 1000);
}
}
}, {
NAME : AJAXEXCEPTION_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
/**
* The error message given in the exception.
*
* @attribute error
* @type String
* @default 'Unknown error'
* @optional
*/
error : {
validator : Y.Lang.isString,
value : 'Unknown error'
},
/**
* Any additional debug information given in the exception.
*
* @attribute stacktrace
* @type String|null
* @default null
* @optional
*/
debuginfo : {
value : null
},
/**
* The complete stack trace provided in the exception.
*
* @attribute stacktrace
* @type String|null
* @default null
* @optional
*/
stacktrace : {
value : null
},
/**
* A link which may be used by support staff to replicate the issue.
*
* @attribute reproductionlink
* @type String
* @default null
* @optional
*/
reproductionlink : {
setter : function(link) {
if (link !== null) {
link = '<a href="'+link+'">'+link.replace(M.cfg.wwwroot, '')+'</a>';
}
return link;
},
value : null
},
/**
* If set, the dialogue is hidden after the specified timeout period.
*
* @attribute hideTimeoutDelay
* @type Number
* @default null
* @optional
*/
hideTimeoutDelay : {
validator : Y.Lang.isNumber,
value : null
}
}
});
M.core.ajaxException = AJAXEXCEPTION;

95
lib/yui/src/notification/js/alert.js vendored Normal file
View File

@ -0,0 +1,95 @@
/**
* A dialogue type designed to display an alert to the user.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-alert
*/
var ALERT_NAME = 'Moodle alert',
ALERT;
/**
* Extends core Dialogue to show the alert dialogue.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.alert
* @extends M.core.dialogue
*/
ALERT = function(config) {
config.closeButton = false;
ALERT.superclass.constructor.apply(this, [config]);
};
Y.extend(ALERT, M.core.dialogue, {
_enterKeypress : null,
initializer : function() {
this.publish('complete');
var yes = Y.Node.create('<input type="button" id="id_yuialertconfirm-' + this.get('COUNT') + '" value="'+this.get(CONFIRMYES)+'" />'),
content = Y.Node.create('<div class="confirmation-dialogue"></div>')
.append(Y.Node.create('<div class="confirmation-message">'+this.get('message')+'</div>'))
.append(Y.Node.create('<div class="confirmation-buttons"></div>')
.append(yes));
this.get(BASE).addClass('moodle-dialogue-confirm');
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
this.setStdModContent(Y.WidgetStdMod.HEADER,
'<h1 id="moodle-dialogue-'+this.get('COUNT')+'-header-text">' + this.get(TITLE) + '</h1>', Y.WidgetStdMod.REPLACE);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._enterKeypress = Y.on('key', this.submit, window, 'down:13', this);
yes.on('click', this.submit, this);
},
submit : function() {
this._enterKeypress.detach();
this.fire('complete');
this.hide();
this.destroy();
}
}, {
NAME : ALERT_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
/**
* The title of the alert.
*
* @attribute title
* @type String
* @default 'Alert'
*/
title : {
validator : Y.Lang.isString,
value : 'Alert'
},
/**
* The message of the alert.
*
* @attribute message
* @type String
* @default 'Confirm'
*/
message : {
validator : Y.Lang.isString,
value : 'Confirm'
},
/**
* The button text to use to accept the alert.
*
* @attribute yesLabel
* @type String
* @default 'Ok'
*/
yesLabel : {
validator : Y.Lang.isString,
setter : function(txt) {
if (!txt) {
txt = 'Ok';
}
return txt;
},
value : 'Ok'
}
}
});
M.core.alert = ALERT;

114
lib/yui/src/notification/js/confirm.js vendored Normal file
View File

@ -0,0 +1,114 @@
/**
* A dialogue type designed to display a confirmation to the user.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-confirm
*/
var CONFIRM_NAME = 'Moodle confirmation dialogue',
CONFIRM;
/**
* Extends core Dialogue to show the confirmation dialogue.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.confirm
* @extends M.core.dialogue
*/
CONFIRM = function(config) {
CONFIRM.superclass.constructor.apply(this, [config]);
};
Y.extend(CONFIRM, M.core.dialogue, {
_enterKeypress : null,
_escKeypress : null,
initializer : function() {
this.publish('complete');
this.publish('complete-yes');
this.publish('complete-no');
var yes = Y.Node.create('<input type="button" id="id_yuiconfirmyes-' + this.get('COUNT') + '" value="'+this.get(CONFIRMYES)+'" />'),
no = Y.Node.create('<input type="button" id="id_yuiconfirmno-' + this.get('COUNT') + '" value="'+this.get(CONFIRMNO)+'" />'),
content = Y.Node.create('<div class="confirmation-dialogue"></div>')
.append(Y.Node.create('<div class="confirmation-message">'+this.get(QUESTION)+'</div>'))
.append(Y.Node.create('<div class="confirmation-buttons"></div>')
.append(yes)
.append(no));
this.get(BASE).addClass('moodle-dialogue-confirm');
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
this.setStdModContent(Y.WidgetStdMod.HEADER,
'<h1 id="moodle-dialogue-'+this.get('COUNT')+'-header-text">' + this.get(TITLE) + '</h1>', Y.WidgetStdMod.REPLACE);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._enterKeypress = Y.on('key', this.submit, window, 'down:13', this, true);
this._escKeypress = Y.on('key', this.submit, window, 'down:27', this, false);
yes.on('click', this.submit, this, true);
no.on('click', this.submit, this, false);
},
submit : function(e, outcome) {
this._enterKeypress.detach();
this._escKeypress.detach();
this.fire('complete', outcome);
if (outcome) {
this.fire('complete-yes');
} else {
this.fire('complete-no');
}
this.hide();
this.destroy();
}
}, {
NAME : CONFIRM_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
/**
* The button text to use to accept the confirmation.
*
* @attribute yesLabel
* @type String
* @default 'Yes'
*/
yesLabel : {
validator : Y.Lang.isString,
value : 'Yes'
},
/**
* The button text to use to reject the confirmation.
*
* @attribute noLabel
* @type String
* @default 'No'
*/
noLabel : {
validator : Y.Lang.isString,
value : 'No'
},
/**
* The title of the dialogue.
*
* @attribute title
* @type String
* @default 'Confirm'
*/
title : {
validator : Y.Lang.isString,
value : 'Confirm'
},
/**
* The question posed by the dialogue.
*
* @attribute question
* @type String
* @default 'Are you sure?'
*/
question : {
validator : Y.Lang.isString,
value : 'Are you sure?'
}
}
});
Y.augment(CONFIRM, Y.EventTarget);
M.core.confirm = CONFIRM;

180
lib/yui/src/notification/js/dialogue.js vendored Normal file
View File

@ -0,0 +1,180 @@
/**
* The generic dialogue class for use in Moodle.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-dialogue
*/
var DIALOGUE_NAME = 'Moodle dialogue',
DIALOGUE;
/**
* A re-usable dialogue box with Moodle classes applied.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.dialogue
* @extends Y.Panel
*/
DIALOGUE = function(config) {
COUNT++;
var id = 'moodle-dialogue-'+COUNT;
config.notificationBase =
Y.Node.create('<div class="'+CSS.BASE+'">')
.append(Y.Node.create('<div id="'+id+'" role="dialog" aria-labelledby="'+id+'-header-text" class="'+CSS.WRAP+'"></div>')
.append(Y.Node.create('<div class="'+CSS.HEADER+' yui3-widget-hd"></div>'))
.append(Y.Node.create('<div class="'+CSS.BODY+' yui3-widget-bd"></div>'))
.append(Y.Node.create('<div class="'+CSS.FOOTER+' yui3-widget-ft"></div>')));
Y.one(document.body).append(config.notificationBase);
config.srcNode = '#'+id;
config.width = config.width || '400px';
config.visible = config.visible || false;
config.center = config.centered || true;
config.centered = false;
config.COUNT = COUNT;
// lightbox param to keep the stable versions API.
if (config.lightbox !== false) {
config.modal = true;
}
delete config.lightbox;
// closeButton param to keep the stable versions API.
if (config.closeButton === false) {
config.buttons = null;
} else {
config.buttons = [
{
section: Y.WidgetStdMod.HEADER,
classNames: 'closebutton',
action: function () {
this.hide();
}
}
];
}
DIALOGUE.superclass.constructor.apply(this, [config]);
if (config.closeButton !== false) {
// The buttons constructor does not allow custom attributes
this.get('buttons').header[0].setAttribute('title', this.get('closeButtonTitle'));
}
};
Y.extend(DIALOGUE, Y.Panel, {
initializer : function() {
this.after('visibleChange', this.visibilityChanged, this);
this.render();
this.show();
this.set('COUNT', COUNT);
// Workaround upstream YUI bug http://yuilibrary.com/projects/yui3/ticket/2532507
// and allow setting of z-index in theme.
this.get('boundingBox').setStyle('zIndex', null);
},
visibilityChanged : function(e) {
var titlebar;
if (e.attrName === 'visible') {
this.get('maskNode').addClass(CSS.LIGHTBOX);
if (this.get('center') && !e.prevVal && e.newVal) {
this.centerDialogue();
}
if (this.get('draggable')) {
titlebar = '#' + this.get('id') + ' .' + CSS.HEADER;
this.plug(Y.Plugin.Drag, {handles : [titlebar]});
Y.one(titlebar).setStyle('cursor', 'move');
}
}
},
centerDialogue : function() {
var bb = this.get('boundingBox'),
hidden = bb.hasClass(DIALOGUE_PREFIX+'-hidden'),
x, y;
if (hidden) {
bb.setStyle('top', '-1000px').removeClass(DIALOGUE_PREFIX+'-hidden');
}
x = Math.max(Math.round((bb.get('winWidth') - bb.get('offsetWidth'))/2), 15);
y = Math.max(Math.round((bb.get('winHeight') - bb.get('offsetHeight'))/2), 15) + Y.one(window).get('scrollTop');
if (hidden) {
bb.addClass(DIALOGUE_PREFIX+'-hidden');
}
bb.setStyle('left', x).setStyle('top', y);
}
}, {
NAME : DIALOGUE_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
notificationBase : {
},
/**
* Whether to display the dialogue modally and with a
* lightbox style.
*
* @attribute lightbox
* @type Boolean
* @default true
*/
lightbox : {
validator : Y.Lang.isBoolean,
value : true
},
/**
* Whether to display a close button on the dialogue.
*
* Note, we do not recommend hiding the close button as this has
* potential accessibility concerns.
*
* @attribute closeButton
* @type Boolean
* @default true
*/
closeButton : {
validator : Y.Lang.isBoolean,
value : true
},
/**
* The title for the close button if one is to be shown.
*
* @attribute closeButtonTitle
* @type String
* @default 'Close'
*/
closeButtonTitle : {
validator : Y.Lang.isString,
value : 'Close'
},
/**
* Whether to display the dialogue centrally on the screen.
*
* @attribute center
* @type Boolean
* @default true
*/
center : {
validator : Y.Lang.isBoolean,
value : true
},
/**
* Whether to make the dialogue movable around the page.
*
* @attribute draggable
* @type Boolean
* @default false
*/
draggable : {
validator : Y.Lang.isBoolean,
value : false
},
COUNT: {
value: 0
}
}
});
M.core.dialogue = DIALOGUE;

149
lib/yui/src/notification/js/exception.js vendored Normal file
View File

@ -0,0 +1,149 @@
/**
* A dialogue type designed to display an appropriate error when a generic
* javascript error was thrown and caught.
*
* @module moodle-core-notification
* @submodule moodle-core-notification-exception
*/
var EXCEPTION_NAME = 'Moodle exception',
EXCEPTION;
/**
* Extends core Dialogue to show the exception dialogue.
*
* @param {Object} config Object literal specifying the dialogue configuration properties.
* @constructor
* @class M.core.exception
* @extends M.core.dialogue
*/
EXCEPTION = function(config) {
config.width = config.width || (M.cfg.developerdebug)?Math.floor(Y.one(document.body).get('winWidth')/3)+'px':null;
config.closeButton = true;
EXCEPTION.superclass.constructor.apply(this, [config]);
};
Y.extend(EXCEPTION, M.core.dialogue, {
_hideTimeout : null,
_keypress : null,
initializer : function(config) {
var content,
self = this,
delay = this.get('hideTimeoutDelay');
this.get(BASE).addClass('moodle-dialogue-exception');
this.setStdModContent(Y.WidgetStdMod.HEADER,
'<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + config.name + '</h1>', Y.WidgetStdMod.REPLACE);
content = Y.Node.create('<div class="moodle-exception"></div>')
.append(Y.Node.create('<div class="moodle-exception-message">'+this.get('message')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-filename"><label>File:</label> ' +
this.get('fileName')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-linenumber"><label>Line:</label> ' +
this.get('lineNumber')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>' +
this.get('stack')+'</pre></div>'));
if (M.cfg.developerdebug) {
content.all('.moodle-exception-param').removeClass('hidden');
}
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
if (delay) {
this._hideTimeout = setTimeout(function(){self.hide();}, delay);
}
this.after('visibleChange', this.visibilityChanged, this);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._keypress = Y.on('key', this.hide, window, 'down:13,27', this);
this.centerDialogue();
},
visibilityChanged : function(e) {
if (e.attrName === 'visible' && e.prevVal && !e.newVal) {
if (this._keypress) {
this._keypress.detach();
}
var self = this;
setTimeout(function(){self.destroy();}, 1000);
}
}
}, {
NAME : EXCEPTION_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
/**
* The message of the alert.
*
* @attribute message
* @type String
* @default ''
*/
message : {
value : ''
},
/**
* The name of the alert.
*
* @attribute title
* @type String
* @default ''
*/
name : {
value : ''
},
/**
* The name of the file where the error was thrown.
*
* @attribute fileName
* @type String
* @default ''
*/
fileName : {
value : ''
},
/**
* The line number where the error was thrown.
*
* @attribute lineNumber
* @type String
* @default ''
*/
lineNumber : {
value : ''
},
/**
* The backtrace from the error
*
* @attribute lineNumber
* @type String
* @default ''
*/
stack : {
setter : function(str) {
var lines = str.split("\n"),
pattern = new RegExp('^(.+)@('+M.cfg.wwwroot+')?(.{0,75}).*:(\\d+)$'),
i;
for (i in lines) {
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>");
}
return lines.join('');
},
value : ''
},
/**
* If set, the dialogue is hidden after the specified timeout period.
*
* @attribute hideTimeoutDelay
* @type Number
* @default null
* @optional
*/
hideTimeoutDelay : {
validator : Y.Lang.isNumber,
value : null
}
}
});
M.core.exception = EXCEPTION;

View File

@ -1,403 +1,25 @@
var DIALOGUE_NAME = 'Moodle dialogue', /**
DIALOGUE_PREFIX = 'moodle-dialogue', * The notification module provides a standard set of dialogues for use
CONFIRM_NAME = 'Moodle confirmation dialogue', * within Moodle.
EXCEPTION_NAME = 'Moodle exception', *
AJAXEXCEPTION_NAME = 'Moodle AJAX exception', * @module moodle-core-notification
ALERT_NAME = 'Moodle alert', * @main
BASE = 'notificationBase', */
COUNT = 0,
CONFIRMYES = 'yesLabel',
CONFIRMNO = 'noLabel',
TITLE = 'title',
QUESTION = 'question',
CSS = {
BASE : 'moodle-dialogue-base',
WRAP : 'moodle-dialogue-wrap',
HEADER : 'moodle-dialogue-hd',
BODY : 'moodle-dialogue-bd',
CONTENT : 'moodle-dialogue-content',
FOOTER : 'moodle-dialogue-ft',
HIDDEN : 'hidden',
LIGHTBOX : 'moodle-dialogue-lightbox'
},
EXCEPTION,
ALERT,
CONFIRM,
AJAXEXCEPTION,
DIALOGUE;
DIALOGUE = function(config) { /**
COUNT++; * To avoid bringing moodle-core-notification into modules in it's
var id = 'moodle-dialogue-'+COUNT; * entirety, we now recommend using on of the subclasses of
config.notificationBase = * moodle-core-notification. These include:
Y.Node.create('<div class="'+CSS.BASE+'">') * <dl>
.append(Y.Node.create('<div id="'+id+'" role="dialog" aria-labelledby="'+id+'-header-text" class="'+CSS.WRAP+'"></div>') * <dt> moodle-core-notification-dialogue</dt>
.append(Y.Node.create('<div class="'+CSS.HEADER+' yui3-widget-hd"></div>')) * <dt> moodle-core-notification-alert</dt>
.append(Y.Node.create('<div class="'+CSS.BODY+' yui3-widget-bd"></div>')) * <dt> moodle-core-notification-confirm</dt>
.append(Y.Node.create('<div class="'+CSS.FOOTER+' yui3-widget-ft"></div>'))); * <dt> moodle-core-notification-exception</dt>
Y.one(document.body).append(config.notificationBase); * <dt> moodle-core-notification-ajaxexception</dt>
config.srcNode = '#'+id; * </dl>
config.width = config.width || '400px'; *
config.visible = config.visible || false; * @class M.core.notification
config.center = config.centered || true; * @deprecated
config.centered = false; */
Y.log("The moodle-core-notification parent module has been deprecated. " +
// lightbox param to keep the stable versions API. "Please use one of its' subclasses instead.", 'moodle-core-notification', 'warn');
if (config.lightbox !== false) {
config.modal = true;
}
delete config.lightbox;
// closeButton param to keep the stable versions API.
if (config.closeButton === false) {
config.buttons = null;
} else {
config.buttons = [
{
section: Y.WidgetStdMod.HEADER,
classNames: 'closebutton',
action: function () {
this.hide();
}
}
];
}
DIALOGUE.superclass.constructor.apply(this, [config]);
if (config.closeButton !== false) {
// The buttons constructor does not allow custom attributes
this.get('buttons').header[0].setAttribute('title', this.get('closeButtonTitle'));
}
};
Y.extend(DIALOGUE, Y.Panel, {
initializer : function() {
this.after('visibleChange', this.visibilityChanged, this);
this.render();
this.show();
// Workaround upstream YUI bug http://yuilibrary.com/projects/yui3/ticket/2532507
// and allow setting of z-index in theme.
this.get('boundingBox').setStyle('zIndex', null);
},
visibilityChanged : function(e) {
var titlebar;
if (e.attrName === 'visible') {
this.get('maskNode').addClass(CSS.LIGHTBOX);
if (this.get('center') && !e.prevVal && e.newVal) {
this.centerDialogue();
}
if (this.get('draggable')) {
titlebar = '#' + this.get('id') + ' .' + CSS.HEADER;
this.plug(Y.Plugin.Drag, {handles : [titlebar]});
Y.one(titlebar).setStyle('cursor', 'move');
}
}
},
centerDialogue : function() {
var bb = this.get('boundingBox'),
hidden = bb.hasClass(DIALOGUE_PREFIX+'-hidden'),
x, y;
if (hidden) {
bb.setStyle('top', '-1000px').removeClass(DIALOGUE_PREFIX+'-hidden');
}
x = Math.max(Math.round((bb.get('winWidth') - bb.get('offsetWidth'))/2), 15);
y = Math.max(Math.round((bb.get('winHeight') - bb.get('offsetHeight'))/2), 15) + Y.one(window).get('scrollTop');
if (hidden) {
bb.addClass(DIALOGUE_PREFIX+'-hidden');
}
bb.setStyle('left', x).setStyle('top', y);
}
}, {
NAME : DIALOGUE_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
notificationBase : {
},
lightbox : {
validator : Y.Lang.isBoolean,
value : true
},
closeButton : {
validator : Y.Lang.isBoolean,
value : true
},
closeButtonTitle : {
validator : Y.Lang.isString,
value : 'Close'
},
center : {
validator : Y.Lang.isBoolean,
value : true
},
draggable : {
validator : Y.Lang.isBoolean,
value : false
}
}
});
ALERT = function(config) {
config.closeButton = false;
ALERT.superclass.constructor.apply(this, [config]);
};
Y.extend(ALERT, DIALOGUE, {
_enterKeypress : null,
initializer : function() {
this.publish('complete');
var yes = Y.Node.create('<input type="button" id="id_yuialertconfirm-' + this.COUNT + '" value="'+this.get(CONFIRMYES)+'" />'),
content = Y.Node.create('<div class="confirmation-dialogue"></div>')
.append(Y.Node.create('<div class="confirmation-message">'+this.get('message')+'</div>'))
.append(Y.Node.create('<div class="confirmation-buttons"></div>')
.append(yes));
this.get(BASE).addClass('moodle-dialogue-confirm');
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
this.setStdModContent(Y.WidgetStdMod.HEADER, '<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + this.get(TITLE) + '</h1>', Y.WidgetStdMod.REPLACE);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._enterKeypress = Y.on('key', this.submit, window, 'down:13', this);
yes.on('click', this.submit, this);
},
submit : function() {
this._enterKeypress.detach();
this.fire('complete');
this.hide();
this.destroy();
}
}, {
NAME : ALERT_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
title : {
validator : Y.Lang.isString,
value : 'Alert'
},
message : {
validator : Y.Lang.isString,
value : 'Confirm'
},
yesLabel : {
validator : Y.Lang.isString,
setter : function(txt) {
if (!txt) {
txt = 'Ok';
}
return txt;
},
value : 'Ok'
}
}
});
CONFIRM = function(config) {
CONFIRM.superclass.constructor.apply(this, [config]);
};
Y.extend(CONFIRM, DIALOGUE, {
_enterKeypress : null,
_escKeypress : null,
initializer : function() {
this.publish('complete');
this.publish('complete-yes');
this.publish('complete-no');
var yes = Y.Node.create('<input type="button" id="id_yuiconfirmyes-' + this.COUNT + '" value="'+this.get(CONFIRMYES)+'" />'),
no = Y.Node.create('<input type="button" id="id_yuiconfirmno-' + this.COUNT + '" value="'+this.get(CONFIRMNO)+'" />'),
content = Y.Node.create('<div class="confirmation-dialogue"></div>')
.append(Y.Node.create('<div class="confirmation-message">'+this.get(QUESTION)+'</div>'))
.append(Y.Node.create('<div class="confirmation-buttons"></div>')
.append(yes)
.append(no));
this.get(BASE).addClass('moodle-dialogue-confirm');
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
this.setStdModContent(Y.WidgetStdMod.HEADER, '<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + this.get(TITLE) + '</h1>', Y.WidgetStdMod.REPLACE);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._enterKeypress = Y.on('key', this.submit, window, 'down:13', this, true);
this._escKeypress = Y.on('key', this.submit, window, 'down:27', this, false);
yes.on('click', this.submit, this, true);
no.on('click', this.submit, this, false);
},
submit : function(e, outcome) {
this._enterKeypress.detach();
this._escKeypress.detach();
this.fire('complete', outcome);
if (outcome) {
this.fire('complete-yes');
} else {
this.fire('complete-no');
}
this.hide();
this.destroy();
}
}, {
NAME : CONFIRM_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
yesLabel : {
validator : Y.Lang.isString,
value : 'Yes'
},
noLabel : {
validator : Y.Lang.isString,
value : 'No'
},
title : {
validator : Y.Lang.isString,
value : 'Confirm'
},
question : {
validator : Y.Lang.isString,
value : 'Are you sure?'
}
}
});
Y.augment(CONFIRM, Y.EventTarget);
EXCEPTION = function(config) {
config.width = config.width || (M.cfg.developerdebug)?Math.floor(Y.one(document.body).get('winWidth')/3)+'px':null;
config.closeButton = true;
EXCEPTION.superclass.constructor.apply(this, [config]);
};
Y.extend(EXCEPTION, DIALOGUE, {
_hideTimeout : null,
_keypress : null,
initializer : function(config) {
var content,
self = this,
delay = this.get('hideTimeoutDelay');
this.get(BASE).addClass('moodle-dialogue-exception');
this.setStdModContent(Y.WidgetStdMod.HEADER, '<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + config.name + '</h1>', Y.WidgetStdMod.REPLACE);
content = Y.Node.create('<div class="moodle-exception"></div>')
.append(Y.Node.create('<div class="moodle-exception-message">'+this.get('message')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-filename"><label>File:</label> '+this.get('fileName')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-linenumber"><label>Line:</label> '+this.get('lineNumber')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>'+this.get('stack')+'</pre></div>'));
if (M.cfg.developerdebug) {
content.all('.moodle-exception-param').removeClass('hidden');
}
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
if (delay) {
this._hideTimeout = setTimeout(function(){self.hide();}, delay);
}
this.after('visibleChange', this.visibilityChanged, this);
this.after('destroyedChange', function(){this.get(BASE).remove();}, this);
this._keypress = Y.on('key', this.hide, window, 'down:13,27', this);
this.centerDialogue();
},
visibilityChanged : function(e) {
if (e.attrName === 'visible' && e.prevVal && !e.newVal) {
if (this._keypress) {
this._keypress.detach();
}
var self = this;
setTimeout(function(){self.destroy();}, 1000);
}
}
}, {
NAME : EXCEPTION_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
message : {
value : ''
},
name : {
value : ''
},
fileName : {
value : ''
},
lineNumber : {
value : ''
},
stack : {
setter : function(str) {
var lines = str.split("\n"),
pattern = new RegExp('^(.+)@('+M.cfg.wwwroot+')?(.{0,75}).*:(\\d+)$'),
i;
for (i in lines) {
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>");
}
return lines.join('');
},
value : ''
},
hideTimeoutDelay : {
validator : Y.Lang.isNumber,
value : null
}
}
});
AJAXEXCEPTION = function(config) {
config.name = config.name || 'Error';
config.closeButton = true;
AJAXEXCEPTION.superclass.constructor.apply(this, [config]);
};
Y.extend(AJAXEXCEPTION, DIALOGUE, {
_keypress : null,
initializer : function(config) {
var content,
self = this,
delay = this.get('hideTimeoutDelay');
this.get(BASE).addClass('moodle-dialogue-exception');
this.setStdModContent(Y.WidgetStdMod.HEADER, '<h1 id="moodle-dialogue-'+COUNT+'-header-text">' + config.name + '</h1>', Y.WidgetStdMod.REPLACE);
content = Y.Node.create('<div class="moodle-ajaxexception"></div>')
.append(Y.Node.create('<div class="moodle-exception-message">'+this.get('error')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-debuginfo"><label>URL:</label> '+this.get('reproductionlink')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-debuginfo"><label>Debug info:</label> '+this.get('debuginfo')+'</div>'))
.append(Y.Node.create('<div class="moodle-exception-param hidden param-stacktrace"><label>Stack trace:</label> <pre>'+this.get('stacktrace')+'</pre></div>'));
if (M.cfg.developerdebug) {
content.all('.moodle-exception-param').removeClass('hidden');
}
this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
if (delay) {
this._hideTimeout = setTimeout(function(){self.hide();}, delay);
}
this.after('visibleChange', this.visibilityChanged, this);
this._keypress = Y.on('key', this.hide, window, 'down:13, 27', this);
this.centerDialogue();
},
visibilityChanged : function(e) {
if (e.attrName === 'visible' && e.prevVal && !e.newVal) {
var self = this;
this._keypress.detach();
setTimeout(function(){self.destroy();}, 1000);
}
}
}, {
NAME : AJAXEXCEPTION_NAME,
CSS_PREFIX : DIALOGUE_PREFIX,
ATTRS : {
error : {
validator : Y.Lang.isString,
value : 'Unknown error'
},
debuginfo : {
value : null
},
stacktrace : {
value : null
},
reproductionlink : {
setter : function(link) {
if (link !== null) {
link = '<a href="'+link+'">'+link.replace(M.cfg.wwwroot, '')+'</a>';
}
return link;
},
value : null
},
hideTimeoutDelay : {
validator : Y.Lang.isNumber,
value : null
}
}
});
M.core = M.core || {};
M.core.dialogue = DIALOGUE;
M.core.alert = ALERT;
M.core.confirm = CONFIRM;
M.core.exception = EXCEPTION;
M.core.ajaxException = AJAXEXCEPTION;

29
lib/yui/src/notification/js/shared.js vendored Normal file
View File

@ -0,0 +1,29 @@
var DIALOGUE_PREFIX,
BASE,
COUNT,
CONFIRMYES,
CONFIRMNO,
TITLE,
QUESTION,
CSS;
DIALOGUE_PREFIX = 'moodle-dialogue',
BASE = 'notificationBase',
COUNT = 0,
CONFIRMYES = 'yesLabel',
CONFIRMNO = 'noLabel',
TITLE = 'title',
QUESTION = 'question',
CSS = {
BASE : 'moodle-dialogue-base',
WRAP : 'moodle-dialogue-wrap',
HEADER : 'moodle-dialogue-hd',
BODY : 'moodle-dialogue-bd',
CONTENT : 'moodle-dialogue-content',
FOOTER : 'moodle-dialogue-ft',
HIDDEN : 'hidden',
LIGHTBOX : 'moodle-dialogue-lightbox'
};
// Set up the namespace once.
M.core = M.core || {};

View File

@ -1,5 +1,14 @@
{ {
"moodle-core-notification": { "moodle-core-notification": {
"requires": [
"moodle-core-notification-dialogue",
"moodle-core-notification-alert",
"moodle-core-notification-confirm",
"moodle-core-notification-exception",
"moodle-core-notification-ajaxexception"
]
},
"moodle-core-notification-dialogue": {
"requires": [ "requires": [
"base", "base",
"node", "node",
@ -7,5 +16,25 @@
"event-key", "event-key",
"dd-plugin" "dd-plugin"
] ]
},
"moodle-core-notification-alert": {
"requires": [
"moodle-core-notification-dialogue"
]
},
"moodle-core-notification-confirm": {
"requires": [
"moodle-core-notification-dialogue"
]
},
"moodle-core-notification-exception": {
"requires": [
"moodle-core-notification-dialogue"
]
},
"moodle-core-notification-ajaxexception": {
"requires": [
"moodle-core-notification-dialogue"
]
} }
} }