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

Reply via email to