Bartosz Dziewoński has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/397736 )
Change subject: Fix popup direction changing when the "anchor" is partially
offscreen
......................................................................
Fix popup direction changing when the "anchor" is partially offscreen
When the "anchor" (floatable container) is partially offscreen, and
'hideWhenOutOfView' is not disabled, the popup/menu (floatable) gets
hidden. That means we get a 0x0px box when calculating its dimensions,
which in turn means it never has to be clipped.
So, whenever we're checking whether the floatable is clipped, let's
also check if it's completely offscreen.
Bug: T182650
Change-Id: I3568f445d5354c6bedee2c532c538b5e8b64ebe2
---
M src/mixins/FloatableElement.js
M src/toolgroups/PopupToolGroup.js
M src/widgets/MenuSelectWidget.js
M src/widgets/PopupWidget.js
4 files changed, 20 insertions(+), 9 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/oojs/ui refs/changes/36/397736/1
diff --git a/src/mixins/FloatableElement.js b/src/mixins/FloatableElement.js
index c5b6da3..8003ee3 100644
--- a/src/mixins/FloatableElement.js
+++ b/src/mixins/FloatableElement.js
@@ -41,6 +41,7 @@
this.$floatableContainer = null;
this.$floatableWindow = null;
this.$floatableClosestScrollable = null;
+ this.floatableOutOfView = false;
this.onFloatableScrollHandler = this.position.bind( this );
this.onFloatableWindowResizeHandler = this.position.bind( this );
@@ -245,6 +246,15 @@
};
/**
+ * Check if the floatable is offscreen (not visible to the user).
+ *
+ * @return {boolean} Floatable is out of view
+ */
+OO.ui.mixin.FloatableElement.prototype.isFloatableOutOfView = function () {
+ return this.floatableOutOfView;
+}
+
+/**
* Position the floatable below its container.
*
* This should only be done when both of them are attached to the DOM and
visible.
@@ -270,7 +280,8 @@
return this;
}
- if ( this.hideWhenOutOfView && !this.isElementInViewport(
this.$floatableContainer, this.$floatableClosestScrollable ) ) {
+ this.floatableOutOfView = this.hideWhenOutOfView &&
!this.isElementInViewport( this.$floatableContainer,
this.$floatableClosestScrollable );
+ if ( this.floatableOutOfView ) {
this.$floatable.addClass( 'oo-ui-element-hidden' );
return this;
} else {
diff --git a/src/toolgroups/PopupToolGroup.js b/src/toolgroups/PopupToolGroup.js
index 96345dd..3adf7f3 100644
--- a/src/toolgroups/PopupToolGroup.js
+++ b/src/toolgroups/PopupToolGroup.js
@@ -211,7 +211,7 @@
this.$element.addClass( 'oo-ui-popupToolGroup-active
oo-ui-popupToolGroup-left' );
this.setFlags( { progressive: true } );
this.toggleClipping( true );
- if ( this.isClippedHorizontally() ) {
+ if ( this.isClippedHorizontally() ||
this.isFloatableOutOfView() ) {
// Anchoring to the left caused the popup to
clip, so anchor it to the right instead
this.toggleClipping( false );
this.$element
@@ -219,7 +219,7 @@
.addClass( 'oo-ui-popupToolGroup-right'
);
this.toggleClipping( true );
}
- if ( this.isClippedHorizontally() ) {
+ if ( this.isClippedHorizontally() ||
this.isFloatableOutOfView() ) {
// Anchoring to the right also caused the popup
to clip, so just make it fill the container
containerWidth =
this.$clippableScrollableContainer.width();
containerLeft =
this.$clippableScrollableContainer[ 0 ] === document.documentElement ?
diff --git a/src/widgets/MenuSelectWidget.js b/src/widgets/MenuSelectWidget.js
index a11d3a2..5beb7b0 100644
--- a/src/widgets/MenuSelectWidget.js
+++ b/src/widgets/MenuSelectWidget.js
@@ -357,11 +357,11 @@
this.togglePositioning( !!this.$floatableContainer );
this.toggleClipping( true );
- if ( this.isClippedVertically() ) {
+ if ( this.isClippedVertically() ||
this.isFloatableOutOfView() ) {
// If opening the menu downwards causes it to
be clipped, flip it to open upwards instead
belowHeight = this.$element.height();
this.setVerticalPosition( 'above' );
- if ( this.isClippedVertically() ) {
+ if ( this.isClippedVertically() ||
this.isFloatableOutOfView() ) {
// If opening upwards also causes it to
be clipped, flip it to open in whichever direction
// we have more space
aboveHeight = this.$element.height();
diff --git a/src/widgets/PopupWidget.js b/src/widgets/PopupWidget.js
index d0ca042..6711cbc 100644
--- a/src/widgets/PopupWidget.js
+++ b/src/widgets/PopupWidget.js
@@ -340,13 +340,13 @@
if ( this.autoFlip ) {
if ( this.popupPosition === 'above' ||
this.popupPosition === 'below' ) {
- if ( this.isClippedVertically() ) {
+ if ( this.isClippedVertically() ||
this.isFloatableOutOfView() ) {
// If opening the popup in the
normal direction causes it to be clipped, open
// in the opposite one instead
normalHeight =
this.$element.height();
this.isAutoFlipped =
!this.isAutoFlipped;
this.position();
- if ( this.isClippedVertically()
) {
+ if ( this.isClippedVertically()
|| this.isFloatableOutOfView() ) {
// If that also causes
it to be clipped, open in whichever direction
// we have more space
oppositeHeight =
this.$element.height();
@@ -358,7 +358,7 @@
}
}
if ( this.popupPosition === 'before' ||
this.popupPosition === 'after' ) {
- if ( this.isClippedHorizontally() ) {
+ if ( this.isClippedHorizontally() ||
this.isFloatableOutOfView() ) {
// If opening the popup in the
normal direction causes it to be clipped, open
// in the opposite one instead
normalWidth =
this.$element.width();
@@ -368,7 +368,7 @@
this.toggleClipping( false );
this.position();
this.toggleClipping( true );
- if (
this.isClippedHorizontally() ) {
+ if (
this.isClippedHorizontally() || this.isFloatableOutOfView() ) {
// If that also causes
it to be clipped, open in whichever direction
// we have more space
oppositeWidth =
this.$element.width();
--
To view, visit https://gerrit.wikimedia.org/r/397736
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3568f445d5354c6bedee2c532c538b5e8b64ebe2
Gerrit-PatchSet: 1
Gerrit-Project: oojs/ui
Gerrit-Branch: master
Gerrit-Owner: Bartosz Dziewoński <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits