MDL-39851 M.core.dialogue: Various fixes

Items addressed
* Get rid of custom attribute srcNode
* Change extraClasses to a config only parameter.
* Change attribute fullscreen to a method.
* Restore the original window overflow value.
* Use setStyles instead of setStyle for performance.
* Tinymce end the zindex wars
* Prevent fullscreen dialogs in an iframe (tinymce managefiles plugin).
* tinymce: Cross browser fix for zindex on popups
* Use CSS for overflow changes (easier to keep track of the previous state).
* Fix Coding style for css changes
This commit is contained in:
Damyon Wiese
2013-08-13 10:42:01 +08:00
parent c4bb131928
commit bf7c86cfcf
14 changed files with 652 additions and 314 deletions
@@ -56,7 +56,7 @@
};
ed.windowManager.onClose.add(onClose);
var vp = ed.dom.getViewPort(),
width = 865 + parseInt(ed.getLang('advimage.delta_width', 0)),
width = 900 + parseInt(ed.getLang('advimage.delta_width', 0)),
height = 600 + parseInt(ed.getLang('advimage.delta_height', 0)),
maximizedmode = (width >= vp.w - 2 || height >= vp.h - 2);
if (maximizedmode) {
+5 -5
View File
@@ -112,10 +112,10 @@ M.form_filemanager.init = function(Y, options) {
this.selectui = new M.core.dialogue({
draggable : true,
headerContent: '<span id="' + labelid +'">' + M.str.moodle.edit + '</span>',
srcNode : this.selectnode,
bodyContent : this.selectnode,
centered : true,
modal : true,
visible : false,
visible : false
});
Y.one('#'+this.selectnode.get('id')).setAttribute('aria-labelledby', labelid);
this.selectui.hide();
@@ -243,7 +243,7 @@ M.form_filemanager.init = function(Y, options) {
this.msg_dlg = new M.core.dialogue({
draggable : true,
srcNode : this.msg_dlg_node,
bodyContent : this.msg_dlg_node,
centered : true,
modal : true,
visible : false,
@@ -321,7 +321,7 @@ M.form_filemanager.init = function(Y, options) {
var node = Y.Node.createWithFilesSkin(M.form_filemanager.templates.mkdir);
this.mkdir_dialog = new M.core.dialogue({
draggable : true,
srcNode : node,
bodyContent : node,
centered : true,
modal : true,
visible : false,
@@ -737,7 +737,7 @@ M.form_filemanager.init = function(Y, options) {
node.generateID();
this.confirm_dlg = new M.core.dialogue({
draggable : true,
srcNode : node,
bodyContent : node,
centered : true,
modal : true,
visible : false,
@@ -17,9 +17,6 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, {
// Any event listeners we may need to cancel later
listenevents : [],
// The initial overflow setting
initialoverflow : '',
bodycontent : null,
headercontent : null,
instanceconfig : null,
@@ -89,14 +86,6 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, {
bb = this.panel.get('boundingBox');
dialogue = this.container.one('.alloptions');
// Get the overflow setting when the chooser was opened - we
// may need this later
if (Y.UA.ie > 0) {
this.initialoverflow = Y.one('html').getStyle('overflow');
} else {
this.initialoverflow = Y.one('body').getStyle('overflow');
}
// This will detect a change in orientation and retrigger centering
thisevent = Y.one('document').on('orientationchange', function() {
this.center_dialogue(dialogue);
@@ -199,11 +188,9 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, {
center_dialogue : function(dialogue) {
var bb = this.panel.get('boundingBox'),
winheight = bb.get('winHeight'),
winwidth = bb.get('winWidth'),
offsettop = 0,
newheight, totalheight, dialoguetop, dialoguewidth, dialogueleft;
newheight, totalheight;
if (this.panel.get('fullscreen')) {
if (this.panel.shouldResizeFullscreen()) {
// No custom sizing required for a fullscreen dialog.
return;
}
@@ -257,13 +244,6 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, {
// Cancel all listen events
this.cancel_listenevents();
// Re-enable the page scrollbars
if (Y.UA.ie > 0) {
Y.one('html').setStyle('overflow', this.initialoverflow);
} else {
Y.one('body').setStyle('overflow', this.initialoverflow);
}
this.container.detachAll();
this.panel.hide();
},
@@ -1 +1 @@
YUI.add("moodle-core-chooserdialogue",function(e,t){var n=function(){n.superclass.constructor.apply(this,arguments)};e.extend(n,e.Base,{panel:null,submitbutton:null,container:null,listenevents:[],initialoverflow:"",bodycontent:null,headercontent:null,instanceconfig:null,setup_chooser_dialogue:function(e,t,n){this.bodycontent=e,this.headercontent=t,this.instanceconfig=n},prepare_chooser:function(){if(this.panel)return;var e,t={bodyContent:this.bodycontent.get("innerHTML"),headerContent:this.headercontent.get("innerHTML"),width:"540px",draggable:!0,visible:!1,zindex:100,lightbox:!0,shim:!0,closeButtonTitle:this.get("closeButtonTitle")};for(e in this.instanceconfig)t[e]=this.instanceconfig[e];this.panel=new M.core.dialogue(t),this.bodycontent.remove(),this.headercontent.remove(),this.panel.hide(),this.panel.render(),this.container=this.panel.get("boundingBox").one(".choosercontainer"),this.options=this.container.all(".option input[type=radio]"),this.panel.get("boundingBox").addClass("chooserdialogue")},display_chooser:function(t){var n,r,i;this.prepare_chooser(),t.preventDefault(),n=this.panel.get("boundingBox"),r=this.container.one(".alloptions"),e.UA.ie>0?this.initialoverflow=e.one("html").getStyle("overflow"):this.initialoverflow=e.one("body").getStyle("overflow"),i=e.one("document").on("orientationchange",function(){this.center_dialogue(r)},this),this.listenevents.push(i),i=e.one("window").on("resize",function(){this.center_dialogue(r)},this),this.listenevents.push(i),i=this.container.on("click",this.check_options,this),this.listenevents.push(i),i=this.container.on("key_up",this.check_options,this),this.listenevents.push(i),i=this.container.on("dblclick",function(e){e.target.ancestor("div.option")&&(this.check_options(),this.submitbutton.setAttribute("disabled","disabled"),this.options.setAttribute("disabled","disabled"),this.cancel_listenevents(),this.container.one("form").submit())},this),this.listenevents.push(i),this.container.one("form").on("submit",function(){this.submitbutton.setAttribute("disabled","disabled"),this.options.setAttribute("disabled","disabled"),this.cancel_listenevents()},this),i=this.container.one(".addcancel").on("click",this.cancel_popup,this),this.listenevents.push(i),i=n.one("button.closebutton").on("click",this.cancel_popup,this),this.listenevents.push(i),i=e.one("document").on("keydown",this.handle_key_press,this),this.listenevents.push(i),this.jumplink=this.container.one(".jump"),this.submitbutton=this.container.one(".submitbutton"),this.submitbutton.set("disabled","true"),this.options.removeAttribute("disabled"),this.panel.show(),this.center_dialogue(r),this.container.one(".option input[type=radio]").focus(),this.check_options()},cancel_listenevents:function(){var e;while(this.listenevents.length)e=this.listenevents.shift(),e.detach()},center_dialogue:function(e){var t=this.panel.get("boundingBox"),n=t.get("winHeight"),r=t.get("winWidth"),i=0,s,o,u,a,f;if(this.panel.get("fullscreen"))return;s=this.get("maxheight"),n<=s&&(n<=this.get("minheight")?s=this.get("minheight"):s=n),o=s,s-=110,e.setStyle("maxHeight",s+"px"),dialogueheight=t.getStyle("height"),dialogueheight.match(/.*px$/)?dialogueheight=dialogueheight.replace(/px$/,""):dialogueheight=o,dialogueheight<this.get("baseheight")&&(dialogueheight=this.get("baseheight"),e.setStyle("height",dialogueheight+"px")),this.panel.centerDialogue()},handle_key_press:function(e){e.keyCode===27&&this.cancel_popup(e)},cancel_popup:function(e){e.preventDefault(),this.hide()},hide:function(){this.cancel_listenevents(),e.UA.ie>0?e.one("html").setStyle("overflow",this.initialoverflow):e.one("body").setStyle("overflow",this.initialoverflow),this.container.detachAll(),this.panel.hide()},check_options:function(){this.options.each(function(e){var t=e.get("parentNode").get("parentNode");e.get("checked")?(t.addClass("selected"),this.option_selected(e),this.submitbutton.removeAttribute("disabled"),e.focus()):t.removeClass("selected")},this)},option_selected:function(){}},{NAME:"moodle-core-chooserdialogue",ATTRS:{minheight:{value:300},baseheight:{value:400},maxheight:{value:660},closeButtonTitle:{validator:e.Lang.isString,value:"Close"}}}),M.core=M.core||{},M.core.chooserdialogue=n},"@VERSION@",{requires:["base","panel","moodle-core-notification"]});
YUI.add("moodle-core-chooserdialogue",function(e,t){var n=function(){n.superclass.constructor.apply(this,arguments)};e.extend(n,e.Base,{panel:null,submitbutton:null,container:null,listenevents:[],bodycontent:null,headercontent:null,instanceconfig:null,setup_chooser_dialogue:function(e,t,n){this.bodycontent=e,this.headercontent=t,this.instanceconfig=n},prepare_chooser:function(){if(this.panel)return;var e,t={bodyContent:this.bodycontent.get("innerHTML"),headerContent:this.headercontent.get("innerHTML"),width:"540px",draggable:!0,visible:!1,zindex:100,lightbox:!0,shim:!0,closeButtonTitle:this.get("closeButtonTitle")};for(e in this.instanceconfig)t[e]=this.instanceconfig[e];this.panel=new M.core.dialogue(t),this.bodycontent.remove(),this.headercontent.remove(),this.panel.hide(),this.panel.render(),this.container=this.panel.get("boundingBox").one(".choosercontainer"),this.options=this.container.all(".option input[type=radio]"),this.panel.get("boundingBox").addClass("chooserdialogue")},display_chooser:function(t){var n,r,i;this.prepare_chooser(),t.preventDefault(),n=this.panel.get("boundingBox"),r=this.container.one(".alloptions"),i=e.one("document").on("orientationchange",function(){this.center_dialogue(r)},this),this.listenevents.push(i),i=e.one("window").on("resize",function(){this.center_dialogue(r)},this),this.listenevents.push(i),i=this.container.on("click",this.check_options,this),this.listenevents.push(i),i=this.container.on("key_up",this.check_options,this),this.listenevents.push(i),i=this.container.on("dblclick",function(e){e.target.ancestor("div.option")&&(this.check_options(),this.submitbutton.setAttribute("disabled","disabled"),this.options.setAttribute("disabled","disabled"),this.cancel_listenevents(),this.container.one("form").submit())},this),this.listenevents.push(i),this.container.one("form").on("submit",function(){this.submitbutton.setAttribute("disabled","disabled"),this.options.setAttribute("disabled","disabled"),this.cancel_listenevents()},this),i=this.container.one(".addcancel").on("click",this.cancel_popup,this),this.listenevents.push(i),i=n.one("button.closebutton").on("click",this.cancel_popup,this),this.listenevents.push(i),i=e.one("document").on("keydown",this.handle_key_press,this),this.listenevents.push(i),this.jumplink=this.container.one(".jump"),this.submitbutton=this.container.one(".submitbutton"),this.submitbutton.set("disabled","true"),this.options.removeAttribute("disabled"),this.panel.show(),this.center_dialogue(r),this.container.one(".option input[type=radio]").focus(),this.check_options()},cancel_listenevents:function(){var e;while(this.listenevents.length)e=this.listenevents.shift(),e.detach()},center_dialogue:function(e){var t=this.panel.get("boundingBox"),n=t.get("winHeight"),r,i;if(this.panel.shouldResizeFullscreen())return;r=this.get("maxheight"),n<=r&&(n<=this.get("minheight")?r=this.get("minheight"):r=n),i=r,r-=110,e.setStyle("maxHeight",r+"px"),dialogueheight=t.getStyle("height"),dialogueheight.match(/.*px$/)?dialogueheight=dialogueheight.replace(/px$/,""):dialogueheight=i,dialogueheight<this.get("baseheight")&&(dialogueheight=this.get("baseheight"),e.setStyle("height",dialogueheight+"px")),this.panel.centerDialogue()},handle_key_press:function(e){e.keyCode===27&&this.cancel_popup(e)},cancel_popup:function(e){e.preventDefault(),this.hide()},hide:function(){this.cancel_listenevents(),this.container.detachAll(),this.panel.hide()},check_options:function(){this.options.each(function(e){var t=e.get("parentNode").get("parentNode");e.get("checked")?(t.addClass("selected"),this.option_selected(e),this.submitbutton.removeAttribute("disabled"),e.focus()):t.removeClass("selected")},this)},option_selected:function(){}},{NAME:"moodle-core-chooserdialogue",ATTRS:{minheight:{value:300},baseheight:{value:400},maxheight:{value:660},closeButtonTitle:{validator:e.Lang.isString,value:"Close"}}}),M.core=M.core||{},M.core.chooserdialogue=n},"@VERSION@",{requires:["base","panel","moodle-core-notification"]});
@@ -17,9 +17,6 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, {
// Any event listeners we may need to cancel later
listenevents : [],
// The initial overflow setting
initialoverflow : '',
bodycontent : null,
headercontent : null,
instanceconfig : null,
@@ -89,14 +86,6 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, {
bb = this.panel.get('boundingBox');
dialogue = this.container.one('.alloptions');
// Get the overflow setting when the chooser was opened - we
// may need this later
if (Y.UA.ie > 0) {
this.initialoverflow = Y.one('html').getStyle('overflow');
} else {
this.initialoverflow = Y.one('body').getStyle('overflow');
}
// This will detect a change in orientation and retrigger centering
thisevent = Y.one('document').on('orientationchange', function() {
this.center_dialogue(dialogue);
@@ -199,11 +188,9 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, {
center_dialogue : function(dialogue) {
var bb = this.panel.get('boundingBox'),
winheight = bb.get('winHeight'),
winwidth = bb.get('winWidth'),
offsettop = 0,
newheight, totalheight, dialoguetop, dialoguewidth, dialogueleft;
newheight, totalheight;
if (this.panel.get('fullscreen')) {
if (this.panel.shouldResizeFullscreen()) {
// No custom sizing required for a fullscreen dialog.
return;
}
@@ -257,13 +244,6 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, {
// Cancel all listen events
this.cancel_listenevents();
// Re-enable the page scrollbars
if (Y.UA.ie > 0) {
Y.one('html').setStyle('overflow', this.initialoverflow);
} else {
Y.one('body').setStyle('overflow', this.initialoverflow);
}
this.container.detachAll();
this.panel.hide();
},
@@ -37,7 +37,17 @@ M.core = M.core || {};
*/
var DIALOGUE_NAME = 'Moodle dialogue',
DIALOGUE;
DIALOGUE,
DIALOGUE_FULLSCREEN_CLASS,
DIALOGUE_HIDDEN_CLASS,
EXISTING_WINDOW_SELECTOR,
NOSCROLLING_CLASS;
DIALOGUE_MODAL_CLASS = 'yui3-widget-modal';
DIALOGUE_FULLSCREEN_CLASS = DIALOGUE_PREFIX+'-fullscreen';
DIALOGUE_HIDDEN_CLASS = DIALOGUE_PREFIX+'-hidden';
EXISTING_WINDOW_SELECTOR = '[role=dialog]';
NOSCROLLING_CLASS = 'no-scrolling';
/**
* A re-usable dialogue box with Moodle classes applied.
@@ -49,12 +59,7 @@ var DIALOGUE_NAME = 'Moodle dialogue',
*/
DIALOGUE = function(config) {
COUNT++;
var id = 'moodle-dialogue-'+COUNT, inputSrcNode = false, contentNode;
if (config.srcNode) {
// We need to reparent this source node to the dialog.
inputSrcNode = config.srcNode;
}
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>')
@@ -98,12 +103,6 @@ DIALOGUE = function(config) {
}
];
}
if (inputSrcNode) {
contentNode = Y.one(inputSrcNode);
// Do we need to remove it?
contentNode.get('parentNode').removeChild(contentNode);
Y.one('#' + id + ' .' + CSS.BODY).append(contentNode);
}
DIALOGUE.superclass.constructor.apply(this, [config]);
if (config.closeButton !== false) {
@@ -117,26 +116,115 @@ Y.extend(DIALOGUE, Y.Panel, {
// Orientation change event listener.
_orientationevent : null,
initializer : function() {
var bb, classes, extraclass;
this.after('visibleChange', this.visibilityChanged, this);
/**
* Initialise the dialogue.
*
* @method initializer
* @return void
*/
initializer : function(config) {
var bb;
this.render();
this.show();
this.after('visibleChange', this.visibilityChanged, this);
if (!config.visible) {
this.hide();
}
this.set('COUNT', COUNT);
// Workaround upstream YUI bug http://yuilibrary.com/projects/yui3/ticket/2532507
// and allow setting of z-index in theme.
bb = this.get('boundingBox');
bb.setStyle('zIndex', null);
// Add the list of extra classes to the bounding box for this dialog (for styling).
classes = this.get('extraClasses').split(' ');
extraclass = classes.pop();
while (typeof extraclass !== "undefined") {
bb.addClass(extraclass);
extraclass = classes.shift();
if (config.extraClasses) {
Y.Array.each(config.extraClasses, bb.addClass, bb);
}
if (config.visible) {
this.applyZIndex();
}
},
/**
* Either set the zindex to the supplied value, or set it to one more than the highest existing
* dialog in the page.
*
* @method visibilityChanged
* @return void
*/
applyZIndex : function() {
var highestzindex = 0,
zindex,
bb;
bb = this.get('boundingBox');
if (this.get('zIndex')) {
// The zindex was specified so we should use that.
bb.setStyle('zIndex', this.get('zIndex'));
} else {
// Determine the correct zindex by looking at all existing dialogs in the page.
// Get the zindex of the parent of each wrapper node.
Y.all(EXISTING_WINDOW_SELECTOR).each(function (node) {
zindex = node.getStyle('zIndex');
// In most cases the zindex is set on the parent of the dialog.
if (!zindex) {
zindex = node.get('parentNode').getStyle('zIndex');
}
if (zindex) {
zindex = parseInt(zindex, 10);
if (zindex > highestzindex) {
highestzindex = zindex;
}
}
});
// Only set the zindex if we found a wrapper.
if (highestzindex > 0) {
bb.setStyle('zIndex', highestzindex + 1);
}
}
},
/**
* Enable or disable document scrolling (see if there are any modal or fullscreen popups).
*
* @method toggleDocumentScrolling
* @param Boolean scroll - If true, allow document scrolling.
* @return void
*/
toggleDocumentScrolling : function() {
var windowroot = Y.one(Y.config.doc.body),
scroll = true,
search;
search = '.' + DIALOGUE_FULLSCREEN_CLASS + ', .' + DIALOGUE_MODAL_CLASS;
Y.all(search).each(function (node) {
if (!node.hasClass(DIALOGUE_HIDDEN_CLASS)) {
scroll = false;
}
});
if (Y.UA.ie > 0) {
// Remember the previous value:
windowroot = Y.one('html');
}
if (scroll) {
if (windowroot.hasClass(NOSCROLLING_CLASS)) {
windowroot.removeClass(NOSCROLLING_CLASS);
}
} else {
windowroot.addClass(NOSCROLLING_CLASS);
}
},
/**
* Event listener for the visibility changed event.
*
* @method visibilityChanged
* @return void
*/
visibilityChanged : function(e) {
var titlebar;
if (e.attrName === 'visible') {
@@ -151,75 +239,98 @@ Y.extend(DIALOGUE, Y.Panel, {
this._orientationevent = null;
}
}
if (!e.prevVal && e.newVal) {
// This needs to be done each time the dialog is shown as new dialogs may have been opened.
this.applyZIndex();
// This needs to be done each time the dialog is shown as the window may have been resized.
this.makeResponsive();
if (!this.shouldResizeFullscreen()) {
if (this.get('draggable')) {
titlebar = '#' + this.get('id') + ' .' + CSS.HEADER;
this.plug(Y.Plugin.Drag, {handles : [titlebar]});
Y.one(titlebar).setStyle('cursor', 'move');
}
}
}
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');
}
this.toggleDocumentScrolling();
}
},
centerDialogue : function() {
/**
* If the responsive attribute is set on the dialog, and the window size is
* smaller than the responsive width - make the dialog fullscreen.
*
* @method makeResponsive
* @return void
*/
makeResponsive : function() {
var bb = this.get('boundingBox'),
hidden = bb.hasClass(DIALOGUE_PREFIX+'-hidden'),
content, x, y;
if (hidden) {
bb.setStyle('top', '-1000px').removeClass(DIALOGUE_PREFIX+'-hidden');
}
if (this.get('fullscreen')) {
content;
if (this.shouldResizeFullscreen()) {
// Make this dialogue fullscreen on a small screen.
// Disable the page scrollbars.
if (Y.UA.ie > 0) {
Y.one('html').setStyle('overflow', 'hidden');
} else {
Y.one('body').setStyle('overflow', 'hidden');
}
// Size and position the fullscreen dialog.
bb.addClass(DIALOGUE_PREFIX+'-fullscreen');
bb.setStyle('left', '0px')
.setStyle('top', '0px')
.setStyle('width', '100%')
.setStyle('height', '100%')
.setStyle('overflow', 'auto');
bb.setStyles({'left' : null, 'top' : null, 'width' : null, 'height' : null});
content = Y.one('#' + this.get('id') + ' .' + CSS.BODY);
content.setStyle('overflow', 'auto');
window.scrollTo(0, 0);
} else {
if (this.get('responsive')) {
// We must reset any of the fullscreen changes.
bb.removeClass(DIALOGUE_PREFIX+'-fullscreen')
.setStyle('overflow', 'inherit')
.setStyle('width', this.get('width'))
.setStyle('height', this.get('height'));
.setStyles({'overflow' : 'inherit',
'width' : this.get('width'),
'height' : this.get('height')});
content = Y.one('#' + this.get('id') + ' .' + CSS.BODY);
content.setStyle('overflow', 'inherit');
if (Y.UA.ie > 0) {
Y.one('html').setStyle('overflow', 'auto');
} else {
Y.one('body').setStyle('overflow', 'auto');
}
}
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');
bb.setStyle('left', x).setStyle('top', y);
}
if (hidden) {
bb.addClass(DIALOGUE_PREFIX+'-hidden');
}
},
hide : function() {
if (Y.UA.ie > 0) {
Y.one('html').setStyle('overflow', 'auto');
} else {
Y.one('body').setStyle('overflow', 'auto');
/**
* Center the dialog on the screen.
*
* @method centerDialogue
* @return void
*/
centerDialogue : function() {
var bb = this.get('boundingBox'),
hidden = bb.hasClass(DIALOGUE_HIDDEN_CLASS),
x,
y;
// Don't adjust the position if we are in full screen mode.
if (this.shouldResizeFullscreen()) {
return;
}
return this.set("visible", false);
if (hidden) {
bb.setStyle('top', '-1000px').removeClass(DIALOGUE_HIDDEN_CLASS);
}
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');
bb.setStyles({ 'left' : x, 'top' : y});
if (hidden) {
bb.addClass(DIALOGUE_HIDDEN_CLASS);
}
},
/**
* Return if this dialogue should be fullscreen or not.
* Responsive attribute must be true and we should not be in an iframe and the screen width should
* be less than the responsive width.
*
* @method shouldResizeFullscreen
* @return Boolean
*/
shouldResizeFullscreen : function() {
return (window === window.parent) && this.get('responsive') &&
Math.floor(Y.one(document.body).get('winWidth')) < this.get('responsiveWidth');
}
}, {
NAME : DIALOGUE_NAME,
@@ -292,25 +403,39 @@ Y.extend(DIALOGUE, Y.Panel, {
validator : Y.Lang.isBoolean,
value : false
},
/**
* Used to generate a unique id for the dialogue.
*
* @attribute COUNT
* @type Integer
* @default 0
*/
COUNT: {
value: 0
},
/**
* Used to disable the fullscreen resizing behaviour if required.
*
* @attribute responsive
* @type Boolean
* @default true
*/
responsive : {
validator : Y.Lang.isBoolean,
value : true
},
/**
* The width that this dialogue should be resized to fullscreen.
*
* @attribute responsiveWidth
* @type Integer
* @default 768
*/
responsiveWidth : {
value : 768
},
extraClasses : {
validator : Y.Lang.isString,
value : ''
},
fullscreen : {
getter : function() {
return this.get('responsive') &&
Math.floor(Y.one(document.body).get('winWidth')) < this.get('responsiveWidth');
}
}
}
});
@@ -1 +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,r=!1,s;t.srcNode&&(r=t.srcNode),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 id="'+n+'-header-text" 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.additionalBaseClass&&t.notificationBase.addClass(t.additionalBaseClass),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.width==="auto"&&delete t.width,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()}}],r&&(s=e.one(r),s.get("parentNode").removeChild(s),e.one("#"+n+" ."+f.BODY).append(s)),c.superclass.constructor.apply(this,[t]),t.closeButton!==!1&&this.get("buttons").header[0].setAttribute("title",this.get("closeButtonTitle"))},e.extend(c,e.Panel,{_resizeevent:null,_orientationevent:null,initializer:function(){var e,t,n;this.after("visibleChange",this.visibilityChanged,this),this.render(),this.show(),this.set("COUNT",i),e=this.get("boundingBox"),e.setStyle("zIndex",null),t=this.get("extraClasses").split(" "),n=t.pop();while(typeof n!="undefined")e.addClass(n),n=t.shift()},visibilityChanged:function(t){var n;t.attrName==="visible"&&(this.get("maskNode").addClass(f.LIGHTBOX),t.prevVal&&!t.newVal&&(this._resizeevent&&(this._resizeevent.detach(),this._resizeevent=null),this._orientationevent&&(this._orientationevent.detach(),this._orientationevent=null)),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,o;r&&t.setStyle("top","-1000px").removeClass(n+"-hidden"),this.get("fullscreen")?(e.UA.ie>0?e.one("html").setStyle("overflow","hidden"):e.one("body").setStyle("overflow","hidden"),t.addClass(n+"-fullscreen"),t.setStyle("left","0px").setStyle("top","0px").setStyle("width","100%").setStyle("height","100%").setStyle("overflow","auto"),i=e.one("#"+this.get("id")+" ."+f.BODY),i.setStyle("overflow","auto"),window.scrollTo(0,0)):(this.get("responsive")&&(t.removeClass(n+"-fullscreen").setStyle("overflow","inherit").setStyle("width",this.get("width")).setStyle("height",this.get("height")),i=e.one("#"+this.get("id")+" ."+f.BODY),i.setStyle("overflow","inherit"),e.UA.ie>0?e.one("html").setStyle("overflow","auto"):e.one("body").setStyle("overflow","auto")),s=Math.max(Math.round((t.get("winWidth")-t.get("offsetWidth"))/2),15),o=Math.max(Math.round((t.get("winHeight")-t.get("offsetHeight"))/2),15)+e.one(window).get("scrollTop"),t.setStyle("left",s).setStyle("top",o)),r&&t.addClass(n+"-hidden")},hide:function(){return e.UA.ie>0?e.one("html").setStyle("overflow","auto"):e.one("body").setStyle("overflow","auto"),this.set("visible",!1)}},{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},responsive:{validator:e.Lang.isBoolean,value:!0},responsiveWidth:{value:768},extraClasses:{validator:e.Lang.isString,value:""},fullscreen:{getter:function(){return this.get("responsive")&&Math.floor(e.one(document.body).get("winWidth"))<this.get("responsiveWidth")}}}}),M.core.dialogue=c},"@VERSION@",{requires:["base","node","panel","event-key","dd-plugin"]});
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,h,p,d,v;DIALOGUE_MODAL_CLASS="yui3-widget-modal",h=n+"-fullscreen",p=n+"-hidden",d="[role=dialog]",v="no-scrolling",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 id="'+n+'-header-text" 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.additionalBaseClass&&t.notificationBase.addClass(t.additionalBaseClass),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.width==="auto"&&delete t.width,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,{_resizeevent:null,_orientationevent:null,initializer:function(t){var n;this.render(),this.show(),this.after("visibleChange",this.visibilityChanged,this),t.visible||this.hide(),this.set("COUNT",i),n=this.get("boundingBox"),t.extraClasses&&e.Array.each(t.extraClasses,n.addClass,n),t.visible&&this.applyZIndex()},applyZIndex:function(){var t=0,n,r;r=this.get("boundingBox"),this.get("zIndex")?r.setStyle("zIndex",this.get("zIndex")):(e.all(d).each(function(e){n=e.getStyle("zIndex"),n||(n=e.get("parentNode").getStyle("zIndex")),n&&(n=parseInt(n,10),n>t&&(t=n))}),t>0&&r.setStyle("zIndex",t+1))},toggleDocumentScrolling:function(){var t=e.one(e.config.doc.body),n=!0,r;r="."+h+", ."+DIALOGUE_MODAL_CLASS,e.all(r).each(function(e){e.hasClass(p)||(n=!1)}),e.UA.ie>0&&(t=e.one("html")),n?t.hasClass(v)&&t.removeClass(v):t.addClass(v)},visibilityChanged:function(t){var n;t.attrName==="visible"&&(this.get("maskNode").addClass(f.LIGHTBOX),t.prevVal&&!t.newVal&&(this._resizeevent&&(this._resizeevent.detach(),this._resizeevent=null),this._orientationevent&&(this._orientationevent.detach(),this._orientationevent=null)),!t.prevVal&&t.newVal&&(this.applyZIndex(),this.makeResponsive(),this.shouldResizeFullscreen()||this.get("draggable")&&(n="#"+this.get("id")+" ."+f.HEADER,this.plug(e.Plugin.Drag,{handles:[n]}),e.one(n).setStyle("cursor","move"))),this.get("center")&&!t.prevVal&&t.newVal&&this.centerDialogue(),this.toggleDocumentScrolling())},makeResponsive:function(){var t=this.get("boundingBox"),r;this.shouldResizeFullscreen()?(t.addClass(n+"-fullscreen"),t.setStyles({left:null,top:null,width:null,height:null}),r=e.one("#"+this.get("id")+" ."+f.BODY),r.setStyle("overflow","auto")):this.get("responsive")&&(t.removeClass(n+"-fullscreen").setStyles({overflow:"inherit",width:this.get("width"),height:this.get("height")}),r=e.one("#"+this.get("id")+" ."+f.BODY),r.setStyle("overflow","inherit"))},centerDialogue:function(){var t=this.get("boundingBox"),n=t.hasClass(p),r,i;if(this.shouldResizeFullscreen())return;n&&t.setStyle("top","-1000px").removeClass(p),r=Math.max(Math.round((t.get("winWidth")-t.get("offsetWidth"))/2),15),i=Math.max(Math.round((t.get("winHeight")-t.get("offsetHeight"))/2),15)+e.one(window).get("scrollTop"),t.setStyles({left:r,top:i}),n&&t.addClass(p)},shouldResizeFullscreen:function(){return window===window.parent&&this.get("responsive")&&Math.floor(e.one(document.body).get("winWidth"))<this.get("responsiveWidth")}},{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},responsive:{validator:e.Lang.isBoolean,value:!0},responsiveWidth:{value:768}}}),M.core.dialogue=c},"@VERSION@",{requires:["base","node","panel","event-key","dd-plugin"]});
@@ -37,7 +37,17 @@ M.core = M.core || {};
*/
var DIALOGUE_NAME = 'Moodle dialogue',
DIALOGUE;
DIALOGUE,
DIALOGUE_FULLSCREEN_CLASS,
DIALOGUE_HIDDEN_CLASS,
EXISTING_WINDOW_SELECTOR,
NOSCROLLING_CLASS;
DIALOGUE_MODAL_CLASS = 'yui3-widget-modal';
DIALOGUE_FULLSCREEN_CLASS = DIALOGUE_PREFIX+'-fullscreen';
DIALOGUE_HIDDEN_CLASS = DIALOGUE_PREFIX+'-hidden';
EXISTING_WINDOW_SELECTOR = '[role=dialog]';
NOSCROLLING_CLASS = 'no-scrolling';
/**
* A re-usable dialogue box with Moodle classes applied.
@@ -49,12 +59,7 @@ var DIALOGUE_NAME = 'Moodle dialogue',
*/
DIALOGUE = function(config) {
COUNT++;
var id = 'moodle-dialogue-'+COUNT, inputSrcNode = false, contentNode;
if (config.srcNode) {
// We need to reparent this source node to the dialog.
inputSrcNode = config.srcNode;
}
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>')
@@ -98,12 +103,6 @@ DIALOGUE = function(config) {
}
];
}
if (inputSrcNode) {
contentNode = Y.one(inputSrcNode);
// Do we need to remove it?
contentNode.get('parentNode').removeChild(contentNode);
Y.one('#' + id + ' .' + CSS.BODY).append(contentNode);
}
DIALOGUE.superclass.constructor.apply(this, [config]);
if (config.closeButton !== false) {
@@ -117,26 +116,115 @@ Y.extend(DIALOGUE, Y.Panel, {
// Orientation change event listener.
_orientationevent : null,
initializer : function() {
var bb, classes, extraclass;
this.after('visibleChange', this.visibilityChanged, this);
/**
* Initialise the dialogue.
*
* @method initializer
* @return void
*/
initializer : function(config) {
var bb;
this.render();
this.show();
this.after('visibleChange', this.visibilityChanged, this);
if (!config.visible) {
this.hide();
}
this.set('COUNT', COUNT);
// Workaround upstream YUI bug http://yuilibrary.com/projects/yui3/ticket/2532507
// and allow setting of z-index in theme.
bb = this.get('boundingBox');
bb.setStyle('zIndex', null);
// Add the list of extra classes to the bounding box for this dialog (for styling).
classes = this.get('extraClasses').split(' ');
extraclass = classes.pop();
while (typeof extraclass !== "undefined") {
bb.addClass(extraclass);
extraclass = classes.shift();
if (config.extraClasses) {
Y.Array.each(config.extraClasses, bb.addClass, bb);
}
if (config.visible) {
this.applyZIndex();
}
},
/**
* Either set the zindex to the supplied value, or set it to one more than the highest existing
* dialog in the page.
*
* @method visibilityChanged
* @return void
*/
applyZIndex : function() {
var highestzindex = 0,
zindex,
bb;
bb = this.get('boundingBox');
if (this.get('zIndex')) {
// The zindex was specified so we should use that.
bb.setStyle('zIndex', this.get('zIndex'));
} else {
// Determine the correct zindex by looking at all existing dialogs in the page.
// Get the zindex of the parent of each wrapper node.
Y.all(EXISTING_WINDOW_SELECTOR).each(function (node) {
zindex = node.getStyle('zIndex');
// In most cases the zindex is set on the parent of the dialog.
if (!zindex) {
zindex = node.get('parentNode').getStyle('zIndex');
}
if (zindex) {
zindex = parseInt(zindex, 10);
if (zindex > highestzindex) {
highestzindex = zindex;
}
}
});
// Only set the zindex if we found a wrapper.
if (highestzindex > 0) {
bb.setStyle('zIndex', highestzindex + 1);
}
}
},
/**
* Enable or disable document scrolling (see if there are any modal or fullscreen popups).
*
* @method toggleDocumentScrolling
* @param Boolean scroll - If true, allow document scrolling.
* @return void
*/
toggleDocumentScrolling : function() {
var windowroot = Y.one(Y.config.doc.body),
scroll = true,
search;
search = '.' + DIALOGUE_FULLSCREEN_CLASS + ', .' + DIALOGUE_MODAL_CLASS;
Y.all(search).each(function (node) {
if (!node.hasClass(DIALOGUE_HIDDEN_CLASS)) {
scroll = false;
}
});
if (Y.UA.ie > 0) {
// Remember the previous value:
windowroot = Y.one('html');
}
if (scroll) {
if (windowroot.hasClass(NOSCROLLING_CLASS)) {
windowroot.removeClass(NOSCROLLING_CLASS);
}
} else {
windowroot.addClass(NOSCROLLING_CLASS);
}
},
/**
* Event listener for the visibility changed event.
*
* @method visibilityChanged
* @return void
*/
visibilityChanged : function(e) {
var titlebar;
if (e.attrName === 'visible') {
@@ -151,75 +239,98 @@ Y.extend(DIALOGUE, Y.Panel, {
this._orientationevent = null;
}
}
if (!e.prevVal && e.newVal) {
// This needs to be done each time the dialog is shown as new dialogs may have been opened.
this.applyZIndex();
// This needs to be done each time the dialog is shown as the window may have been resized.
this.makeResponsive();
if (!this.shouldResizeFullscreen()) {
if (this.get('draggable')) {
titlebar = '#' + this.get('id') + ' .' + CSS.HEADER;
this.plug(Y.Plugin.Drag, {handles : [titlebar]});
Y.one(titlebar).setStyle('cursor', 'move');
}
}
}
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');
}
this.toggleDocumentScrolling();
}
},
centerDialogue : function() {
/**
* If the responsive attribute is set on the dialog, and the window size is
* smaller than the responsive width - make the dialog fullscreen.
*
* @method makeResponsive
* @return void
*/
makeResponsive : function() {
var bb = this.get('boundingBox'),
hidden = bb.hasClass(DIALOGUE_PREFIX+'-hidden'),
content, x, y;
if (hidden) {
bb.setStyle('top', '-1000px').removeClass(DIALOGUE_PREFIX+'-hidden');
}
if (this.get('fullscreen')) {
content;
if (this.shouldResizeFullscreen()) {
// Make this dialogue fullscreen on a small screen.
// Disable the page scrollbars.
if (Y.UA.ie > 0) {
Y.one('html').setStyle('overflow', 'hidden');
} else {
Y.one('body').setStyle('overflow', 'hidden');
}
// Size and position the fullscreen dialog.
bb.addClass(DIALOGUE_PREFIX+'-fullscreen');
bb.setStyle('left', '0px')
.setStyle('top', '0px')
.setStyle('width', '100%')
.setStyle('height', '100%')
.setStyle('overflow', 'auto');
bb.setStyles({'left' : null, 'top' : null, 'width' : null, 'height' : null});
content = Y.one('#' + this.get('id') + ' .' + CSS.BODY);
content.setStyle('overflow', 'auto');
window.scrollTo(0, 0);
} else {
if (this.get('responsive')) {
// We must reset any of the fullscreen changes.
bb.removeClass(DIALOGUE_PREFIX+'-fullscreen')
.setStyle('overflow', 'inherit')
.setStyle('width', this.get('width'))
.setStyle('height', this.get('height'));
.setStyles({'overflow' : 'inherit',
'width' : this.get('width'),
'height' : this.get('height')});
content = Y.one('#' + this.get('id') + ' .' + CSS.BODY);
content.setStyle('overflow', 'inherit');
if (Y.UA.ie > 0) {
Y.one('html').setStyle('overflow', 'auto');
} else {
Y.one('body').setStyle('overflow', 'auto');
}
}
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');
bb.setStyle('left', x).setStyle('top', y);
}
if (hidden) {
bb.addClass(DIALOGUE_PREFIX+'-hidden');
}
},
hide : function() {
if (Y.UA.ie > 0) {
Y.one('html').setStyle('overflow', 'auto');
} else {
Y.one('body').setStyle('overflow', 'auto');
/**
* Center the dialog on the screen.
*
* @method centerDialogue
* @return void
*/
centerDialogue : function() {
var bb = this.get('boundingBox'),
hidden = bb.hasClass(DIALOGUE_HIDDEN_CLASS),
x,
y;
// Don't adjust the position if we are in full screen mode.
if (this.shouldResizeFullscreen()) {
return;
}
return this.set("visible", false);
if (hidden) {
bb.setStyle('top', '-1000px').removeClass(DIALOGUE_HIDDEN_CLASS);
}
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');
bb.setStyles({ 'left' : x, 'top' : y});
if (hidden) {
bb.addClass(DIALOGUE_HIDDEN_CLASS);
}
},
/**
* Return if this dialogue should be fullscreen or not.
* Responsive attribute must be true and we should not be in an iframe and the screen width should
* be less than the responsive width.
*
* @method shouldResizeFullscreen
* @return Boolean
*/
shouldResizeFullscreen : function() {
return (window === window.parent) && this.get('responsive') &&
Math.floor(Y.one(document.body).get('winWidth')) < this.get('responsiveWidth');
}
}, {
NAME : DIALOGUE_NAME,
@@ -292,25 +403,39 @@ Y.extend(DIALOGUE, Y.Panel, {
validator : Y.Lang.isBoolean,
value : false
},
/**
* Used to generate a unique id for the dialogue.
*
* @attribute COUNT
* @type Integer
* @default 0
*/
COUNT: {
value: 0
},
/**
* Used to disable the fullscreen resizing behaviour if required.
*
* @attribute responsive
* @type Boolean
* @default true
*/
responsive : {
validator : Y.Lang.isBoolean,
value : true
},
/**
* The width that this dialogue should be resized to fullscreen.
*
* @attribute responsiveWidth
* @type Integer
* @default 768
*/
responsiveWidth : {
value : 768
},
extraClasses : {
validator : Y.Lang.isString,
value : ''
},
fullscreen : {
getter : function() {
return this.get('responsive') &&
Math.floor(Y.one(document.body).get('winWidth')) < this.get('responsiveWidth');
}
}
}
});
+2 -22
View File
@@ -15,9 +15,6 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, {
// Any event listeners we may need to cancel later
listenevents : [],
// The initial overflow setting
initialoverflow : '',
bodycontent : null,
headercontent : null,
instanceconfig : null,
@@ -87,14 +84,6 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, {
bb = this.panel.get('boundingBox');
dialogue = this.container.one('.alloptions');
// Get the overflow setting when the chooser was opened - we
// may need this later
if (Y.UA.ie > 0) {
this.initialoverflow = Y.one('html').getStyle('overflow');
} else {
this.initialoverflow = Y.one('body').getStyle('overflow');
}
// This will detect a change in orientation and retrigger centering
thisevent = Y.one('document').on('orientationchange', function() {
this.center_dialogue(dialogue);
@@ -197,11 +186,9 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, {
center_dialogue : function(dialogue) {
var bb = this.panel.get('boundingBox'),
winheight = bb.get('winHeight'),
winwidth = bb.get('winWidth'),
offsettop = 0,
newheight, totalheight, dialoguetop, dialoguewidth, dialogueleft;
newheight, totalheight;
if (this.panel.get('fullscreen')) {
if (this.panel.shouldResizeFullscreen()) {
// No custom sizing required for a fullscreen dialog.
return;
}
@@ -255,13 +242,6 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, {
// Cancel all listen events
this.cancel_listenevents();
// Re-enable the page scrollbars
if (Y.UA.ie > 0) {
Y.one('html').setStyle('overflow', this.initialoverflow);
} else {
Y.one('body').setStyle('overflow', this.initialoverflow);
}
this.container.detachAll();
this.panel.hide();
},
+202 -77
View File
@@ -6,7 +6,17 @@
*/
var DIALOGUE_NAME = 'Moodle dialogue',
DIALOGUE;
DIALOGUE,
DIALOGUE_FULLSCREEN_CLASS,
DIALOGUE_HIDDEN_CLASS,
EXISTING_WINDOW_SELECTOR,
NOSCROLLING_CLASS;
DIALOGUE_MODAL_CLASS = 'yui3-widget-modal';
DIALOGUE_FULLSCREEN_CLASS = DIALOGUE_PREFIX+'-fullscreen';
DIALOGUE_HIDDEN_CLASS = DIALOGUE_PREFIX+'-hidden';
EXISTING_WINDOW_SELECTOR = '[role=dialog]';
NOSCROLLING_CLASS = 'no-scrolling';
/**
* A re-usable dialogue box with Moodle classes applied.
@@ -18,12 +28,7 @@ var DIALOGUE_NAME = 'Moodle dialogue',
*/
DIALOGUE = function(config) {
COUNT++;
var id = 'moodle-dialogue-'+COUNT, inputSrcNode = false, contentNode;
if (config.srcNode) {
// We need to reparent this source node to the dialog.
inputSrcNode = config.srcNode;
}
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>')
@@ -67,12 +72,6 @@ DIALOGUE = function(config) {
}
];
}
if (inputSrcNode) {
contentNode = Y.one(inputSrcNode);
// Do we need to remove it?
contentNode.get('parentNode').removeChild(contentNode);
Y.one('#' + id + ' .' + CSS.BODY).append(contentNode);
}
DIALOGUE.superclass.constructor.apply(this, [config]);
if (config.closeButton !== false) {
@@ -86,26 +85,115 @@ Y.extend(DIALOGUE, Y.Panel, {
// Orientation change event listener.
_orientationevent : null,
initializer : function() {
var bb, classes, extraclass;
this.after('visibleChange', this.visibilityChanged, this);
/**
* Initialise the dialogue.
*
* @method initializer
* @return void
*/
initializer : function(config) {
var bb;
this.render();
this.show();
this.after('visibleChange', this.visibilityChanged, this);
if (!config.visible) {
this.hide();
}
this.set('COUNT', COUNT);
// Workaround upstream YUI bug http://yuilibrary.com/projects/yui3/ticket/2532507
// and allow setting of z-index in theme.
bb = this.get('boundingBox');
bb.setStyle('zIndex', null);
// Add the list of extra classes to the bounding box for this dialog (for styling).
classes = this.get('extraClasses').split(' ');
extraclass = classes.pop();
while (typeof extraclass !== "undefined") {
bb.addClass(extraclass);
extraclass = classes.shift();
if (config.extraClasses) {
Y.Array.each(config.extraClasses, bb.addClass, bb);
}
if (config.visible) {
this.applyZIndex();
}
},
/**
* Either set the zindex to the supplied value, or set it to one more than the highest existing
* dialog in the page.
*
* @method visibilityChanged
* @return void
*/
applyZIndex : function() {
var highestzindex = 0,
zindex,
bb;
bb = this.get('boundingBox');
if (this.get('zIndex')) {
// The zindex was specified so we should use that.
bb.setStyle('zIndex', this.get('zIndex'));
} else {
// Determine the correct zindex by looking at all existing dialogs in the page.
// Get the zindex of the parent of each wrapper node.
Y.all(EXISTING_WINDOW_SELECTOR).each(function (node) {
zindex = node.getStyle('zIndex');
// In most cases the zindex is set on the parent of the dialog.
if (!zindex) {
zindex = node.get('parentNode').getStyle('zIndex');
}
if (zindex) {
zindex = parseInt(zindex, 10);
if (zindex > highestzindex) {
highestzindex = zindex;
}
}
});
// Only set the zindex if we found a wrapper.
if (highestzindex > 0) {
bb.setStyle('zIndex', highestzindex + 1);
}
}
},
/**
* Enable or disable document scrolling (see if there are any modal or fullscreen popups).
*
* @method toggleDocumentScrolling
* @param Boolean scroll - If true, allow document scrolling.
* @return void
*/
toggleDocumentScrolling : function() {
var windowroot = Y.one(Y.config.doc.body),
scroll = true,
search;
search = '.' + DIALOGUE_FULLSCREEN_CLASS + ', .' + DIALOGUE_MODAL_CLASS;
Y.all(search).each(function (node) {
if (!node.hasClass(DIALOGUE_HIDDEN_CLASS)) {
scroll = false;
}
});
if (Y.UA.ie > 0) {
// Remember the previous value:
windowroot = Y.one('html');
}
if (scroll) {
if (windowroot.hasClass(NOSCROLLING_CLASS)) {
windowroot.removeClass(NOSCROLLING_CLASS);
}
} else {
windowroot.addClass(NOSCROLLING_CLASS);
}
},
/**
* Event listener for the visibility changed event.
*
* @method visibilityChanged
* @return void
*/
visibilityChanged : function(e) {
var titlebar;
if (e.attrName === 'visible') {
@@ -120,75 +208,98 @@ Y.extend(DIALOGUE, Y.Panel, {
this._orientationevent = null;
}
}
if (!e.prevVal && e.newVal) {
// This needs to be done each time the dialog is shown as new dialogs may have been opened.
this.applyZIndex();
// This needs to be done each time the dialog is shown as the window may have been resized.
this.makeResponsive();
if (!this.shouldResizeFullscreen()) {
if (this.get('draggable')) {
titlebar = '#' + this.get('id') + ' .' + CSS.HEADER;
this.plug(Y.Plugin.Drag, {handles : [titlebar]});
Y.one(titlebar).setStyle('cursor', 'move');
}
}
}
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');
}
this.toggleDocumentScrolling();
}
},
centerDialogue : function() {
/**
* If the responsive attribute is set on the dialog, and the window size is
* smaller than the responsive width - make the dialog fullscreen.
*
* @method makeResponsive
* @return void
*/
makeResponsive : function() {
var bb = this.get('boundingBox'),
hidden = bb.hasClass(DIALOGUE_PREFIX+'-hidden'),
content, x, y;
if (hidden) {
bb.setStyle('top', '-1000px').removeClass(DIALOGUE_PREFIX+'-hidden');
}
if (this.get('fullscreen')) {
content;
if (this.shouldResizeFullscreen()) {
// Make this dialogue fullscreen on a small screen.
// Disable the page scrollbars.
if (Y.UA.ie > 0) {
Y.one('html').setStyle('overflow', 'hidden');
} else {
Y.one('body').setStyle('overflow', 'hidden');
}
// Size and position the fullscreen dialog.
bb.addClass(DIALOGUE_PREFIX+'-fullscreen');
bb.setStyle('left', '0px')
.setStyle('top', '0px')
.setStyle('width', '100%')
.setStyle('height', '100%')
.setStyle('overflow', 'auto');
bb.setStyles({'left' : null, 'top' : null, 'width' : null, 'height' : null});
content = Y.one('#' + this.get('id') + ' .' + CSS.BODY);
content.setStyle('overflow', 'auto');
window.scrollTo(0, 0);
} else {
if (this.get('responsive')) {
// We must reset any of the fullscreen changes.
bb.removeClass(DIALOGUE_PREFIX+'-fullscreen')
.setStyle('overflow', 'inherit')
.setStyle('width', this.get('width'))
.setStyle('height', this.get('height'));
.setStyles({'overflow' : 'inherit',
'width' : this.get('width'),
'height' : this.get('height')});
content = Y.one('#' + this.get('id') + ' .' + CSS.BODY);
content.setStyle('overflow', 'inherit');
if (Y.UA.ie > 0) {
Y.one('html').setStyle('overflow', 'auto');
} else {
Y.one('body').setStyle('overflow', 'auto');
}
}
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');
bb.setStyle('left', x).setStyle('top', y);
}
if (hidden) {
bb.addClass(DIALOGUE_PREFIX+'-hidden');
}
},
hide : function() {
if (Y.UA.ie > 0) {
Y.one('html').setStyle('overflow', 'auto');
} else {
Y.one('body').setStyle('overflow', 'auto');
/**
* Center the dialog on the screen.
*
* @method centerDialogue
* @return void
*/
centerDialogue : function() {
var bb = this.get('boundingBox'),
hidden = bb.hasClass(DIALOGUE_HIDDEN_CLASS),
x,
y;
// Don't adjust the position if we are in full screen mode.
if (this.shouldResizeFullscreen()) {
return;
}
return this.set("visible", false);
if (hidden) {
bb.setStyle('top', '-1000px').removeClass(DIALOGUE_HIDDEN_CLASS);
}
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');
bb.setStyles({ 'left' : x, 'top' : y});
if (hidden) {
bb.addClass(DIALOGUE_HIDDEN_CLASS);
}
},
/**
* Return if this dialogue should be fullscreen or not.
* Responsive attribute must be true and we should not be in an iframe and the screen width should
* be less than the responsive width.
*
* @method shouldResizeFullscreen
* @return Boolean
*/
shouldResizeFullscreen : function() {
return (window === window.parent) && this.get('responsive') &&
Math.floor(Y.one(document.body).get('winWidth')) < this.get('responsiveWidth');
}
}, {
NAME : DIALOGUE_NAME,
@@ -261,25 +372,39 @@ Y.extend(DIALOGUE, Y.Panel, {
validator : Y.Lang.isBoolean,
value : false
},
/**
* Used to generate a unique id for the dialogue.
*
* @attribute COUNT
* @type Integer
* @default 0
*/
COUNT: {
value: 0
},
/**
* Used to disable the fullscreen resizing behaviour if required.
*
* @attribute responsive
* @type Boolean
* @default true
*/
responsive : {
validator : Y.Lang.isBoolean,
value : true
},
/**
* The width that this dialogue should be resized to fullscreen.
*
* @attribute responsiveWidth
* @type Integer
* @default 768
*/
responsiveWidth : {
value : 768
},
extraClasses : {
validator : Y.Lang.isString,
value : ''
},
fullscreen : {
getter : function() {
return this.get('responsive') &&
Math.floor(Y.one(document.body).get('winWidth')) < this.get('responsiveWidth');
}
}
}
});
+12 -8
View File
@@ -717,11 +717,12 @@ M.core_filepicker.init = function(Y, options) {
node.generateID();
this.process_dlg = new M.core.dialogue({
draggable : true,
srcNode : this.fpnode,
bodyContent : this.fpnode,
headerContent: M.str.repository.fileexistsdialogheader,
centered : true,
modal : true,
visible : false,
zIndex : this.options.zIndex
});
node.one('.fp-dlg-butoverwrite').on('click', handleOverwrite, this);
node.one('.fp-dlg-butrename').on('click', handleRename, this);
@@ -757,10 +758,11 @@ M.core_filepicker.init = function(Y, options) {
this.msg_dlg = new M.core.dialogue({
draggable : true,
srcNode : this.msg_dlg_node,
bodyContent : this.msg_dlg_node,
centered : true,
modal : true,
visible : false
visible : false,
zIndex : this.options.zIndex
});
this.msg_dlg_node.one('.fp-msg-butok').on('click', function(e) {
e.preventDefault();
@@ -1283,16 +1285,17 @@ M.core_filepicker.init = function(Y, options) {
this.fpnode = Y.Node.createWithFilesSkin(M.core_filepicker.templates.generallayout).
set('id', 'filepicker-'+client_id);
this.mainui = new M.core.dialogue({
extraClasses : 'filepicker',
extraClasses : ['filepicker'],
draggable : true,
srcNode : this.fpnode,
bodyContent : this.fpnode,
headerContent: M.str.repository.filepicker,
centered : true,
modal : true,
visible : false,
width : '873px',
responsiveWidth : 873,
height : '558px'
height : '558px',
zIndex : this.options.zIndex
});
// create panel for selecting a file (initially hidden)
@@ -1305,13 +1308,13 @@ M.core_filepicker.init = function(Y, options) {
this.selectui = new M.core.dialogue({
headerContent: '<span id="' + fplabel +'">'+M.str.moodle.edit+'</span>',
draggable : true,
srcNode : this.selectnode,
bodyContent : this.selectnode,
centered : true,
modal : true,
visible : false,
zIndex : this.options.zIndex
});
Y.one('#'+this.selectnode.get('id')).setAttribute('aria-labelledby', fplabel);
this.selectui.hide();
// event handler for lazy loading of thumbnails and next page
this.fpnode.one('.fp-content').on(['scroll','resize'], this.content_scrolled, this);
// save template for one path element and location of path bar
@@ -1375,6 +1378,7 @@ M.core_filepicker.init = function(Y, options) {
this.display_error(M.str.repository.norepositoriesavailable, 'norepositoriesavailable')
}
// display repository that was used last time
this.mainui.show();
this.show_recent_repository();
},
parse_repository_options: function(data, appendtolist) {
+9
View File
@@ -906,6 +906,15 @@ sup {vertical-align: super;}
z-index: 600;
}
.no-scrolling { overflow: hidden; }
.moodle-dialogue-fullscreen {
left: 0px;
top: 0px;
width: 100%;
height: 100%;
overflow: auto;
}
.moodle-dialogue-base .moodle-dialogue-wrap {
margin-top:-3px;
+10
View File
@@ -1380,6 +1380,16 @@ audio.mediaplugin_html5audio {
.moodle-dialogue-base .moodle-dialogue-hidden {
display: none;
}
.no-scrolling {
overflow: hidden;
}
.moodle-dialogue-fullscreen {
left: 0px;
top: 0px;
width: 100%;
height: 100%;
overflow: auto;
}
.moodle-dialogue-base .moodle-dialogue {
padding: 0;
margin: 0;
File diff suppressed because one or more lines are too long