mw.page.gallery: Prevent jumpiness due to viewport height changes
authorBartosz Dziewoński <matma.rex@gmail.com>
Tue, 8 May 2018 19:12:00 +0000 (21:12 +0200)
committerBartosz Dziewoński <matma.rex@gmail.com>
Thu, 24 May 2018 18:10:59 +0000 (18:10 +0000)
* Do not recalculate if only viewport height has changed, but not
  width. Viewport height doesn't affect this at all.
* Set a min-height on the gallery element before resetting image
  dimensions so that content following it only reflows once, when
  we calculate dimensions again.

Bug: T194193
Change-Id: I6362863cc0f3f7b76c9ec7437d37ff6762ecf153

resources/src/mediawiki.page.gallery.js

index 79937e5..82ae393 100644 (file)
@@ -5,6 +5,8 @@
 ( function ( mw, $ ) {
        var $galleries,
                bound = false,
+               lastWidth = window.innerWidth,
+               justifyNeeded = false,
                // Is there a better way to detect a touchscreen? Current check taken from stack overflow.
                isTouchScreen = !!( window.ontouchstart !== undefined ||
                        window.DocumentTouch !== undefined && document instanceof window.DocumentTouch
        }
 
        function handleResizeStart() {
+               // Only do anything if window width changed. We don't care about the height.
+               if ( lastWidth === window.innerWidth ) {
+                       return;
+               }
+
+               justifyNeeded = true;
+               // Temporarily set min-height, so that content following the gallery is not reflowed twice
+               $galleries.css( 'min-height', function () {
+                       return $( this ).height();
+               } );
                $galleries.children( 'li.gallerybox' ).each( function () {
                        var imgWidth = $( this ).data( 'imgWidth' ),
                                imgHeight = $( this ).data( 'imgHeight' ),
        }
 
        function handleResizeEnd() {
-               $galleries.each( justify );
+               // If window width never changed during the resize, don't do anything.
+               if ( justifyNeeded ) {
+                       justifyNeeded = false;
+                       lastWidth = window.innerWidth;
+                       $galleries
+                               // Remove temporary min-height
+                               .css( 'min-height', '' )
+                               // Recalculate layout
+                               .each( justify );
+               }
        }
 
        mw.hook( 'wikipage.content' ).add( function ( $content ) {