mirror of
https://github.com/moodle/moodle.git
synced 2025-04-13 20:42:22 +02:00
MDL-47734 core: Prevent jumping of YUI dialogues
When a YUI dialogue was opened, it was focusing on the boundingBox, with the browser moving the scroll position to focus on the top of the boundingBox. This caused a jump. This only happens when the dialogue is modal and consequentially has a maskNode present as it changes the initial positioning behaviour of the boundingBox. To avoid this, when the maskNode is shown, the dialogue is position at 0,0 in the current viewport. For centered dialogues, the dialogue is automatically re-positioned after the window has shown. For non-centered dialogues, the original position is stored and the dialogue is restored to that position after it has been displayed. This should not interfere with use of the align function as this will be called later in the proceedings, after the show has run.
This commit is contained in:
parent
b1b66a3d12
commit
d247a50113
@ -98,6 +98,16 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
_orientationevent : null,
|
||||
_calculatedzindex : false,
|
||||
|
||||
/**
|
||||
* The original position of the dialogue before it was reposition to
|
||||
* avoid browser jumping.
|
||||
*
|
||||
* @property _originalPosition
|
||||
* @protected
|
||||
* @type Array
|
||||
*/
|
||||
_originalPosition: null,
|
||||
|
||||
/**
|
||||
* Initialise the dialogue.
|
||||
*
|
||||
@ -132,14 +142,21 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
}
|
||||
// Recalculate the zIndex every time the modal is altered.
|
||||
this.on('maskShow', this.applyZIndex);
|
||||
// We must show - after the dialogue has been positioned,
|
||||
// either by centerDialogue or makeResonsive. This is because the show() will trigger
|
||||
// a focus on the dialogue, which will scroll the page. If the dialogue has not
|
||||
// been positioned it will scroll back to the top of the page.
|
||||
if (this.get('visible')) {
|
||||
this.show();
|
||||
this.keyDelegation();
|
||||
}
|
||||
|
||||
this.on('maskShow', function() {
|
||||
// When the mask shows, position the boundingBox at the top-left of the window such that when it is
|
||||
// focused, the position does not change.
|
||||
var w = Y.one(Y.config.win),
|
||||
bb = this.get('boundingBox');
|
||||
|
||||
if (!this.get('center')) {
|
||||
this._originalPosition = bb.getXY();
|
||||
}
|
||||
bb.setStyles({
|
||||
top: w.get('scrollTop'),
|
||||
left: w.get('scrollLeft')
|
||||
});
|
||||
}, this);
|
||||
|
||||
// Remove the dialogue from the DOM when it is destroyed.
|
||||
this.after('destroyedChange', function(){
|
||||
@ -325,7 +342,7 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
Math.floor(Y.one(document.body).get('winWidth')) < this.get('responsiveWidth');
|
||||
},
|
||||
|
||||
show : function() {
|
||||
show: function() {
|
||||
var result = null,
|
||||
header = this.headerNode,
|
||||
content = this.bodyNode,
|
||||
@ -334,6 +351,11 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
|
||||
result = DIALOGUE.superclass.show.call(this);
|
||||
|
||||
if (!this.get('center') && this._originalPosition) {
|
||||
// Restore the dialogue position to it's location before it was moved at show time.
|
||||
this.get('boundingBox').setXY(this._originalPosition);
|
||||
}
|
||||
|
||||
// Lock scroll if the plugin is present.
|
||||
if (this.lockScroll) {
|
||||
// We need to force the scroll locking for full screen dialogues, even if they have a small vertical size to
|
||||
|
File diff suppressed because one or more lines are too long
@ -98,6 +98,16 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
_orientationevent : null,
|
||||
_calculatedzindex : false,
|
||||
|
||||
/**
|
||||
* The original position of the dialogue before it was reposition to
|
||||
* avoid browser jumping.
|
||||
*
|
||||
* @property _originalPosition
|
||||
* @protected
|
||||
* @type Array
|
||||
*/
|
||||
_originalPosition: null,
|
||||
|
||||
/**
|
||||
* Initialise the dialogue.
|
||||
*
|
||||
@ -132,14 +142,21 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
}
|
||||
// Recalculate the zIndex every time the modal is altered.
|
||||
this.on('maskShow', this.applyZIndex);
|
||||
// We must show - after the dialogue has been positioned,
|
||||
// either by centerDialogue or makeResonsive. This is because the show() will trigger
|
||||
// a focus on the dialogue, which will scroll the page. If the dialogue has not
|
||||
// been positioned it will scroll back to the top of the page.
|
||||
if (this.get('visible')) {
|
||||
this.show();
|
||||
this.keyDelegation();
|
||||
}
|
||||
|
||||
this.on('maskShow', function() {
|
||||
// When the mask shows, position the boundingBox at the top-left of the window such that when it is
|
||||
// focused, the position does not change.
|
||||
var w = Y.one(Y.config.win),
|
||||
bb = this.get('boundingBox');
|
||||
|
||||
if (!this.get('center')) {
|
||||
this._originalPosition = bb.getXY();
|
||||
}
|
||||
bb.setStyles({
|
||||
top: w.get('scrollTop'),
|
||||
left: w.get('scrollLeft')
|
||||
});
|
||||
}, this);
|
||||
|
||||
// Remove the dialogue from the DOM when it is destroyed.
|
||||
this.after('destroyedChange', function(){
|
||||
@ -325,7 +342,7 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
Math.floor(Y.one(document.body).get('winWidth')) < this.get('responsiveWidth');
|
||||
},
|
||||
|
||||
show : function() {
|
||||
show: function() {
|
||||
var result = null,
|
||||
header = this.headerNode,
|
||||
content = this.bodyNode,
|
||||
@ -334,6 +351,11 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
|
||||
result = DIALOGUE.superclass.show.call(this);
|
||||
|
||||
if (!this.get('center') && this._originalPosition) {
|
||||
// Restore the dialogue position to it's location before it was moved at show time.
|
||||
this.get('boundingBox').setXY(this._originalPosition);
|
||||
}
|
||||
|
||||
// Lock scroll if the plugin is present.
|
||||
if (this.lockScroll) {
|
||||
// We need to force the scroll locking for full screen dialogues, even if they have a small vertical size to
|
||||
|
40
lib/yui/src/notification/js/dialogue.js
vendored
40
lib/yui/src/notification/js/dialogue.js
vendored
@ -69,6 +69,16 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
_orientationevent : null,
|
||||
_calculatedzindex : false,
|
||||
|
||||
/**
|
||||
* The original position of the dialogue before it was reposition to
|
||||
* avoid browser jumping.
|
||||
*
|
||||
* @property _originalPosition
|
||||
* @protected
|
||||
* @type Array
|
||||
*/
|
||||
_originalPosition: null,
|
||||
|
||||
/**
|
||||
* Initialise the dialogue.
|
||||
*
|
||||
@ -103,14 +113,21 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
}
|
||||
// Recalculate the zIndex every time the modal is altered.
|
||||
this.on('maskShow', this.applyZIndex);
|
||||
// We must show - after the dialogue has been positioned,
|
||||
// either by centerDialogue or makeResonsive. This is because the show() will trigger
|
||||
// a focus on the dialogue, which will scroll the page. If the dialogue has not
|
||||
// been positioned it will scroll back to the top of the page.
|
||||
if (this.get('visible')) {
|
||||
this.show();
|
||||
this.keyDelegation();
|
||||
}
|
||||
|
||||
this.on('maskShow', function() {
|
||||
// When the mask shows, position the boundingBox at the top-left of the window such that when it is
|
||||
// focused, the position does not change.
|
||||
var w = Y.one(Y.config.win),
|
||||
bb = this.get('boundingBox');
|
||||
|
||||
if (!this.get('center')) {
|
||||
this._originalPosition = bb.getXY();
|
||||
}
|
||||
bb.setStyles({
|
||||
top: w.get('scrollTop'),
|
||||
left: w.get('scrollLeft')
|
||||
});
|
||||
}, this);
|
||||
|
||||
// Remove the dialogue from the DOM when it is destroyed.
|
||||
this.after('destroyedChange', function(){
|
||||
@ -296,7 +313,7 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
Math.floor(Y.one(document.body).get('winWidth')) < this.get('responsiveWidth');
|
||||
},
|
||||
|
||||
show : function() {
|
||||
show: function() {
|
||||
var result = null,
|
||||
header = this.headerNode,
|
||||
content = this.bodyNode,
|
||||
@ -305,6 +322,11 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
|
||||
result = DIALOGUE.superclass.show.call(this);
|
||||
|
||||
if (!this.get('center') && this._originalPosition) {
|
||||
// Restore the dialogue position to it's location before it was moved at show time.
|
||||
this.get('boundingBox').setXY(this._originalPosition);
|
||||
}
|
||||
|
||||
// Lock scroll if the plugin is present.
|
||||
if (this.lockScroll) {
|
||||
// We need to force the scroll locking for full screen dialogues, even if they have a small vertical size to
|
||||
|
Loading…
x
Reference in New Issue
Block a user