Bartosz Dziewoński has uploaded a new change for review. https://gerrit.wikimedia.org/r/276664
Change subject: FloatableElement: Hide if the anchor element is outside viewport ...................................................................... FloatableElement: Hide if the anchor element is outside viewport Bug: T129521 Change-Id: I5b5d7936c4de8f89917feb5f548916030bce70f8 --- M src/mixins/FloatableElement.js M src/styles/elements/FloatableElement.less 2 files changed, 66 insertions(+), 10 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/oojs/ui refs/changes/64/276664/1 diff --git a/src/mixins/FloatableElement.js b/src/mixins/FloatableElement.js index ebdd392..55f1f23 100644 --- a/src/mixins/FloatableElement.js +++ b/src/mixins/FloatableElement.js @@ -86,22 +86,19 @@ closestScrollableOfContainer = OO.ui.Element.static.getClosestScrollableContainer( this.$floatableContainer[ 0 ] ); closestScrollableOfFloatable = OO.ui.Element.static.getClosestScrollableContainer( this.$floatable[ 0 ] ); - if ( closestScrollableOfContainer !== closestScrollableOfFloatable ) { - // If the scrollable is the root, we have to listen to scroll events - // on the window because of browser inconsistencies (or do we? someone should verify this) - if ( $( closestScrollableOfContainer ).is( 'html, body' ) ) { - closestScrollableOfContainer = OO.ui.Element.static.getWindow( closestScrollableOfContainer ); - } + this.needsCustomPosition = closestScrollableOfContainer !== closestScrollableOfFloatable; + // If the scrollable is the root, we have to listen to scroll events + // on the window because of browser inconsistencies. + if ( $( closestScrollableOfContainer ).is( 'html, body' ) ) { + closestScrollableOfContainer = OO.ui.Element.static.getWindow( closestScrollableOfContainer ); } if ( positioning ) { this.$floatableWindow = $( this.getElementWindow() ); this.$floatableWindow.on( 'resize', this.onFloatableWindowResizeHandler ); - if ( closestScrollableOfContainer !== closestScrollableOfFloatable ) { - this.$floatableClosestScrollable = $( closestScrollableOfContainer ); - this.$floatableClosestScrollable.on( 'scroll', this.onFloatableScrollHandler ); - } + this.$floatableClosestScrollable = $( closestScrollableOfContainer ); + this.$floatableClosestScrollable.on( 'scroll', this.onFloatableScrollHandler ); // Initial position after visible this.position(); @@ -124,6 +121,50 @@ }; /** + * Check whether the bottom edge of the given element is within the viewport of the given container. + * + * @private + * @param {jQuery} $element + * @param {jQuery} $container + * @return {Boolean} + */ +OO.ui.mixin.FloatableElement.prototype.isElementInViewport = function ( $element, $container ) { + var elemRect, contRect, + topEdgeInBounds = false, + leftEdgeInBounds = false, + bottomEdgeInBounds = false, + rightEdgeInBounds = false; + + elemRect = $element[ 0 ].getBoundingClientRect(); + if ( $container[ 0 ] === window ) { + contRect = { + top: 0, + left: 0, + right: document.documentElement.clientWidth, + bottom: document.documentElement.clientHeight + }; + } else { + contRect = $container[ 0 ].getBoundingClientRect(); + } + + if ( elemRect.top >= contRect.top && elemRect.top <= contRect.bottom ) { + topEdgeInBounds = true; + } + if ( elemRect.left >= contRect.left && elemRect.left <= contRect.right ) { + leftEdgeInBounds = true; + } + if ( elemRect.bottom >= contRect.top && elemRect.bottom <= contRect.bottom ) { + bottomEdgeInBounds = true; + } + if ( elemRect.right >= contRect.left && elemRect.right <= contRect.right ) { + rightEdgeInBounds = true; + } + + // We only care that any part of the bottom edge is visible + return bottomEdgeInBounds && ( leftEdgeInBounds || rightEdgeInBounds ); +}; + +/** * Position the floatable below its container. * * This should only be done when both of them are attached to the DOM and visible. @@ -137,6 +178,17 @@ return this; } + if ( !this.isElementInViewport( this.$floatableContainer, this.$floatableClosestScrollable ) ) { + this.$floatable.addClass( 'oo-ui-floatableElement-hidden' ); + return; + } else { + this.$floatable.removeClass( 'oo-ui-floatableElement-hidden' ); + } + + if ( !this.needsCustomPosition ) { + return; + } + pos = OO.ui.Element.static.getRelativePosition( this.$floatableContainer, this.$floatable.offsetParent() ); // Position under container diff --git a/src/styles/elements/FloatableElement.less b/src/styles/elements/FloatableElement.less index 293f4fd..6abbf97 100644 --- a/src/styles/elements/FloatableElement.less +++ b/src/styles/elements/FloatableElement.less @@ -1,5 +1,9 @@ @import '../common'; .oo-ui-floatableElement { + &-hidden { + display: none; + } + .theme-oo-ui-floatableElement(); } -- To view, visit https://gerrit.wikimedia.org/r/276664 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5b5d7936c4de8f89917feb5f548916030bce70f8 Gerrit-PatchSet: 1 Gerrit-Project: oojs/ui Gerrit-Branch: master Gerrit-Owner: Bartosz Dziewoński <matma....@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits