Merge "mediawiki.notification: Move offset() computation to next frame"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 4 Oct 2017 21:52:50 +0000 (21:52 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 4 Oct 2017 21:52:50 +0000 (21:52 +0000)
resources/src/mediawiki/mediawiki.notification.js

index d5289bd..20f8b8d 100644 (file)
                                .toggleClass( 'mw-notification-area-layout', !isFloating );
                }
 
+               // Write to the DOM:
                // Prepend the notification area to the content area and save its object.
                $area = $( '<div id="mw-notification-area" class="mw-notification-area mw-notification-area-layout"></div>' )
                        // Pause auto-hide timers when the mouse is in the notification area.
                        } );
 
                mw.util.$content.prepend( $area );
-               offset = $area.offset();
-               $area.css( 'display', 'none' );
 
-               $( window ).on( 'scroll', updateAreaMode );
+               // Read from the DOM:
+               // Must be in the next frame to avoid synchronous layout
+               // computation from offset()/getBoundingClientRect().
+               rAF( function () {
+                       offset = $area.offset();
 
-               // Initial mode
-               updateAreaMode();
+                       // Initial mode (reads, and then maybe writes)
+                       updateAreaMode();
 
-               // Handle pre-ready queue.
-               isPageReady = true;
-               while ( preReadyNotifQueue.length ) {
-                       notif = preReadyNotifQueue.shift();
-                       notif.start();
-               }
+                       // Once we have the offset for where it would normally render, set the
+                       // initial state of the (currently empty) notification area to be hidden.
+                       $area.css( 'display', 'none' );
+
+                       $( window ).on( 'scroll', updateAreaMode );
+
+                       // Handle pre-ready queue.
+                       isPageReady = true;
+                       while ( preReadyNotifQueue.length ) {
+                               notif = preReadyNotifQueue.shift();
+                               notif.start();
+                       }
+               } );
        }
 
        /**