jenkins-bot has submitted this change and it was merged.

Change subject: Fixes to animations (transitions) and notifications
......................................................................


Fixes to animations (transitions) and notifications

Make those animations buttery smooth, glitchless and awesome.

* Put all notifications into a separate #notifications div (helps
  sandbox those transformed elements better, seems to fix blurry text
  for good).
* Create a more universal transition LESS mixin (accepts arbitrary
  number of transitions just like transition CSS property).
* Animate only the required properties for notifications (not all
  properties).
* Provide a reliable fallback for browsers that don't support
  position: fixed (that works both with and without animations).
* Stop treating Firefox and MSIE 10 (Windows Phone 8) as if they didn't
  support position: fixed.

Bug: 50621
Change-Id: I9aa603fae53c36184421c520e911f6e4b9ba5300
---
M javascripts/common/Drawer.js
M javascripts/common/mf-application.js
M javascripts/common/mf-notification.js
M less/common/mainmenu.less
M less/common/mf-common.less
M less/common/notifications.less
M less/mf-mixins.less
M less/modules/mf-watchstar.less
M less/specials/mobilediff.less
M less/specials/uploads.less
M stylesheets/common/mf-common.css
M stylesheets/common/notifications.css
M stylesheets/common/ui.css
M stylesheets/modules/mf-watchstar.css
M stylesheets/specials/mobilediff.css
M stylesheets/specials/uploads.css
16 files changed, 137 insertions(+), 103 deletions(-)

Approvals:
  Jdlrobson: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/javascripts/common/Drawer.js b/javascripts/common/Drawer.js
index caa7d6f..fc3370f 100644
--- a/javascripts/common/Drawer.js
+++ b/javascripts/common/Drawer.js
@@ -13,7 +13,7 @@
                                ev.preventDefault();
                                self.hide();
                        } );
-                       this.appendTo( '#mw-mf-page-center' );
+                       this.appendTo( '#notifications' );
                },
 
                show: function() {
@@ -22,13 +22,16 @@
                                this.$el.addClass( 'visible' );
                                // ignore a possible click that called show()
                                setTimeout( function() {
-                                       $( window ).one( 'scroll click', 
$.proxy( self, 'hide' ) );
+                                       $( window ).one( 'scroll.drawer 
click.drawer', $.proxy( self, 'hide' ) );
                                }, 0 );
                        }
                },
 
                hide: function() {
                        this.$el.removeClass( 'visible' );
+                       // .one() registers one callback for scroll and click 
independently
+                       // if one fired, get rid of the other one
+                       $( window ).off( '.drawer' );
                },
 
                isVisible: function() {
diff --git a/javascripts/common/mf-application.js 
b/javascripts/common/mf-application.js
index 324f178..811111f 100644
--- a/javascripts/common/mf-application.js
+++ b/javascripts/common/mf-application.js
@@ -6,7 +6,7 @@
                // FIXME: when mobileFrontend is an object with a constructor,
                // just inherit from EventEmitter instead
                eventEmitter = new EventEmitter(),
-               $viewport, viewport,
+               $viewportMeta, viewport,
                template,
                templates = {};
 
@@ -59,21 +59,24 @@
                }
        };
 
-       // TODO: only apply to places that need it
        // http://www.quirksmode.org/blog/archives/2010/12/the_fifth_posit.html
        // https://github.com/Modernizr/Modernizr/issues/167
+       // http://mobilehtml5.org/
        function supportsPositionFixed() {
-               // TODO: don't use device detection
-               var agent = navigator.userAgent,
-                       support = false,
-                       supportedAgents = [
-                       // match anything over Webkit 534
+               var support = false;
+               [
+                       // Webkit 534+
+                       // FIXME: this will fail if Webkit goes past 599 and 
for Blink
+                       // (http://www.chromium.org/blink)
                        /AppleWebKit\/(53[4-9]|5[4-9]\d?|[6-9])\d?\d?/,
                        // Android 3+
-                       /Android [3-9]/
-               ];
-               supportedAgents.forEach( function( item ) {
-                       if( agent.match( item ) ) {
+                       /Android [3-9]/,
+                       // any Firefox
+                       /Firefox/,
+                       // MSIE 10+
+                       /MSIE 1\d/
+               ].forEach( function( item ) {
+                       if ( item.test( navigator.userAgent ) ) {
                                support = true;
                        }
                } );
@@ -85,18 +88,20 @@
        }
 
        function lockViewport() {
-               $viewport.attr( 'content', 'minimum-scale=1.0, 
maximum-scale=1.0' );
+               $viewportMeta.attr( 'content', 'minimum-scale=1.0, 
maximum-scale=1.0' );
        }
 
        function unlockViewport() {
-               $viewport.attr( 'content', viewport );
+               $viewportMeta.attr( 'content', viewport );
        }
 
        // TODO: separate main menu navigation code into separate module
        function init() {
                var
                        mode, $body = $( 'body' ),
-                       $doc = $( 'html' );
+                       $doc = $( 'html' ),
+                       $viewport = $( '#mw-mf-viewport' ),
+                       $pageCenter = $( '#mw-mf-page-center' );
 
                if ( $body.hasClass( 'alpha' ) ) {
                        mode = 'alpha';
@@ -106,12 +111,33 @@
                mw.config.set( 'wgMFMode', mode );
 
                $doc.removeClass( 'page-loading' ); // FIXME: Kill with fire. 
This is here for historic reasons in case old HTML is cached
-               if( supportsPositionFixed() ) {
-                       $doc.addClass( 'supportsPositionFixed' );
+
+               $( '<div id="notifications">' ).appendTo( $viewport );
+
+               if ( !supportsPositionFixed() ) {
+                       $doc.addClass( 'no-position-fixed' );
+
+                       $( window ).on( 'scroll', function() {
+                               var scrollTop = $( window ).scrollTop(),
+                                       scrollBottom = scrollTop + $( window 
).height();
+
+                               if ( scrollTop === 0 ) {
+                                       // special case when we're at the 
beginning of the page and many
+                                       // browsers (e.g. Android 2.x) return 
wrong window height because
+                                       // of the URL bar
+                                       $viewport.height( '100%' );
+                               } else if ( scrollBottom < $pageCenter.height() 
) {
+                                       // keep expanding the viewport until 
it's as big as main content
+                                       // (prevents possible infinite scroll 
in some browsers, can be tested
+                                       // on desktop Chrome forcing 
supportsPositionFixed() to return false)
+                                       // #notification has bottom: 0 and 
sticks to the end of the viewport
+                                       $viewport.height( scrollBottom );
+                               }
+                       } );
                }
 
-               $viewport = $( 'meta[name="viewport"]' );
-               viewport = $viewport.attr( 'content' );
+               $viewportMeta = $( 'meta[name="viewport"]' );
+               viewport = $viewportMeta.attr( 'content' );
                // FIXME: If minimum-scale and maximum-scale are not set 
locking viewport will prevent a reset
                if ( viewport && viewport.indexOf( 'minimum-scale' ) === -1 ) {
                        viewport += ', minimum-scale=0.25, maximum-scale=1.6';
@@ -123,7 +149,7 @@
                        // see http://adactio.com/journal/4470/ (fixed in ios 6)
                        var
                                ua = navigator.userAgent;
-                       if( $viewport[0] && ua.match( /iPhone|iPad/i ) && 
ua.match( /OS [4-5]_0/ )  ) {
+                       if( $viewportMeta[0] && ua.match( /iPhone|iPad/i ) && 
ua.match( /OS [4-5]_0/ )  ) {
                                lockViewport();
                                document.addEventListener( 'gesturestart', 
function() {
                                        lockViewport();
diff --git a/javascripts/common/mf-notification.js 
b/javascripts/common/mf-notification.js
index 81542e9..bd0f91d 100644
--- a/javascripts/common/mf-notification.js
+++ b/javascripts/common/mf-notification.js
@@ -4,18 +4,6 @@
                        canCancel = true,
                        inBeta = mw.config.get( 'wgMFMode' ) === 'beta';
 
-               if ( !M.supportsPositionFixed() ) {
-                       calculatePosition = function() {
-                               var h = $( '#mf-notification' ).outerHeight();
-                               $( '#mf-notification' ).css( {
-                                       top:  ( window.innerHeight + 
window.pageYOffset ) - h,
-                                       bottom: 'auto',
-                                       position: 'absolute'
-                               } );
-                       };
-                       $( document ).scroll( calculatePosition );
-               }
-
                function isVisible() {
                        return $( '#mf-notification' ).is( ':visible' );
                }
@@ -54,7 +42,7 @@
                function init( firstRun ) {
                        // FIXME: turn into view with template
                        var el = $( '<div id="mf-notification" 
class="position-fixed"><div></div></div>' ).
-                               appendTo( '#mw-mf-page-center' )[ 0 ];
+                               appendTo( '#notifications' )[ 0 ];
 
                        if ( inBeta ) {
                                notifyAuthenticatedUser();
diff --git a/less/common/mainmenu.less b/less/common/mainmenu.less
index cf05779..9f831f3 100644
--- a/less/common/mainmenu.less
+++ b/less/common/mainmenu.less
@@ -4,7 +4,7 @@
 
 #mw-mf-viewport {
        position: relative;
-       min-height: 100%;
+       height: 100%;
 }
 
 #mw-mf-page-center {
@@ -118,6 +118,7 @@
                margin-left: -@menuBorder;
                // disable horizontal scrolling
                overflow: hidden;
+               height: auto !important;
        }
 
        #mw-mf-page-center {
diff --git a/less/common/mf-common.less b/less/common/mf-common.less
index 5b42819..3f89dc7 100644
--- a/less/common/mf-common.less
+++ b/less/common/mf-common.less
@@ -273,12 +273,20 @@
        display: block;
 }
 
-.supportsPositionFixed {
+.position-fixed {
+       position: fixed;
+       // workaround for:
+       // http://code.google.com/p/chromium/issues/detail?id=20574
+       // (otherwise hidden drawer causes .buttonBar to render incorrectly)
+       .transform( translate3d(0,0,0) );
+}
+
+.no-position-fixed {
+       #notifications {
+               bottom: 0;
+       }
+
        .position-fixed {
-               position: fixed;
-               // workaround for:
-               // http://code.google.com/p/chromium/issues/detail?id=20574
-               // (otherwise hidden drawer causes .buttonBar to render 
incorrectly)
-               .transform( translate3d(0,0,0) );
+               position: absolute;
        }
 }
diff --git a/less/common/notifications.less b/less/common/notifications.less
index 9ef0039..252da5a 100644
--- a/less/common/notifications.less
+++ b/less/common/notifications.less
@@ -1,23 +1,31 @@
 @import "../mf-mixins.less";
 @toastNotificationColor: #373737;
 
+#notifications {
+       // it's only a container, should not get in the way
+       height: 0;
+       // needed for Android 4.x
+       position: absolute;
+       z-index: 5;
+       // needed for MSIE 9 (Windows Phone 7)
+       width: 100%;
+}
+
 /* Notifications */
 #mf-notification,
 .drawer {
-       /* -2px to avoid a weird glitch in some browsers where the popup moves
-        * slightly when scrolling */
-       bottom: -2px;
+       bottom: 0;
        width: 100%;
        background-color: @searchBoxColorTo;
        .boxshadow( 0, -1px, 8px, 0, rgba(0, 0, 0, 0.35) );
        word-wrap: break-word;
-       z-index: -1;
+       // needs to be higher than for overlays to show on top of overlays
+       z-index: 5;
+       // don't use visibility: hidden in old browsers that don't support 
animations
        display: none;
 
        &.visible {
-               // needs to be higher than for overlays to show on top of 
overlays
-               z-index: 5;
-               display: block
+               display: block;
        }
 }
 
@@ -25,19 +33,23 @@
 .animations .alpha {
        #mf-notification,
        .drawer {
+               @duration: .25s;
                display: block;
+               visibility: hidden;
                /* we can't determine the actual size of the drawer in CSS, so 
this is
                 * an estimate; it doesn't have to be exact because it's used 
only for
                 * the sliding animation, not for hiding the drawer */
-               bottom: -11em;
+               .transform( translate3d(0, 100px, 0) );
                opacity: 0;
-               .transition( all, .2s );
+               // delay visibility transition to make other transitions visible
+               // http://fvsch.com/code/transition-fade/test5.html/
+               .transition( transform @duration, opacity @duration, visibility 
0 @duration );
 
                &.visible {
+                       .transition( transform @duration, opacity @duration );
+                       visibility: visible;
                        opacity: 1;
-                       /* -0.2em to avoid a weird glitch in some browsers 
where the popup moves
-                        * slightly when scrolling */
-                       .transform( translate3d(0, -10.8em, 0) );
+                       .transform( translate3d(0, 0, 0) );
                }
        }
 }
@@ -125,7 +137,7 @@
        }
 
        a:visited, a {
-       color: #3354C0;
+               color: #3354C0;
        }
 
        p {
diff --git a/less/mf-mixins.less b/less/mf-mixins.less
index 72b90c2..e496a8f 100644
--- a/less/mf-mixins.less
+++ b/less/mf-mixins.less
@@ -89,16 +89,14 @@
        transform: @transform;
 }
 
-.transition( @property: all, @duration: .2s, @timingFunction: ease ) {
+// http://www.toekneestuck.com/blog/2012/05/15/less-css-arguments-variable/
+.transition( @dummy, @dummier: X, ... ) {
        // avoid Webkit bugs
        -webkit-backface-visibility: hidden;
 
-       -webkit-transition-property: ~`"@{property}" === "transform" ? 
"-webkit-@{property}" : "@{property}"`;
-       transition-property: @property;
-       -webkit-transition-duration: @duration;
-       transition-duration: @duration;
-       -webkit-transition-timing-function: @timingFunction;
-       transition-timing-function: @timingFunction;
+       @args: ~`"@{arguments}".replace(/^\[|(, X)?\]$/g, '')`;
+       -webkit-transition: ~`"@{args}".replace('transform', 
'-webkit-transform')`;
+       transition: @args;
 }
 
 .animation( @name, @duration, @function: ease-in-out, @iterationCount: 
infinite, @direction: alternate ) {
diff --git a/less/modules/mf-watchstar.less b/less/modules/mf-watchstar.less
index a499b07..0846d6c 100644
--- a/less/modules/mf-watchstar.less
+++ b/less/modules/mf-watchstar.less
@@ -11,7 +11,7 @@
 .animations .beta,
 .animations .alpha {
        .watch-this-article {
-               .transition( transform, .5s );
+               .transition( transform .5s );
 
                &.watched {
                        .transform( rotate(72deg) );
diff --git a/less/specials/mobilediff.less b/less/specials/mobilediff.less
index c349d70..1764bad 100644
--- a/less/specials/mobilediff.less
+++ b/less/specials/mobilediff.less
@@ -172,12 +172,10 @@
        }
 }
 
-.supportsPositionFixed {
-       #mw-mf-diffview {
-               #mw-mf-userinfo {
-                       bottom: 0;
-                       left: 0;
-                       right: 0;
-               }
+#mw-mf-diffview {
+       #mw-mf-userinfo {
+               bottom: 0;
+               left: 0;
+               right: 0;
        }
 }
diff --git a/less/specials/uploads.less b/less/specials/uploads.less
index e709ca5..413a760 100644
--- a/less/specials/uploads.less
+++ b/less/specials/uploads.less
@@ -138,7 +138,7 @@
        .slideable {
                .slider {
                        left: 0;
-                       .transition( @duration: .5s );
+                       .transition( .5s );
 
                        &.slider-left {
                                .transform( translate3d(-100%, 0, 0) )
diff --git a/stylesheets/common/mf-common.css b/stylesheets/common/mf-common.css
index 16ad285..f519d05 100644
--- a/stylesheets/common/mf-common.css
+++ b/stylesheets/common/mf-common.css
@@ -226,8 +226,14 @@
 .client-js .jsonly {
   display: block;
 }
-.supportsPositionFixed .position-fixed {
+.position-fixed {
   position: fixed;
   -webkit-transform: translate3d(0, 0, 0);
   transform: translate3d(0, 0, 0);
 }
+.no-position-fixed #notifications {
+  bottom: 0;
+}
+.no-position-fixed .position-fixed {
+  position: absolute;
+}
diff --git a/stylesheets/common/notifications.css 
b/stylesheets/common/notifications.css
index 8b0492b..358858f 100644
--- a/stylesheets/common/notifications.css
+++ b/stylesheets/common/notifications.css
@@ -1,20 +1,22 @@
+#notifications {
+  height: 0;
+  position: absolute;
+  z-index: 5;
+  width: 100%;
+}
 /* Notifications */
 #mf-notification,
 .drawer {
-  /* -2px to avoid a weird glitch in some browsers where the popup moves
-        * slightly when scrolling */
-
-  bottom: -2px;
+  bottom: 0;
   width: 100%;
   background-color: #f3f3f3;
   box-shadow: 0 -1px 8px 0 rgba(0, 0, 0, 0.35);
   word-wrap: break-word;
-  z-index: -1;
+  z-index: 5;
   display: none;
 }
 #mf-notification.visible,
 .drawer.visible {
-  z-index: 5;
   display: block;
 }
 .animations .beta #mf-notification,
@@ -22,30 +24,29 @@
 .animations .beta .drawer,
 .animations .alpha .drawer {
   display: block;
+  visibility: hidden;
   /* we can't determine the actual size of the drawer in CSS, so this is
                 * an estimate; it doesn't have to be exact because it's used 
only for
                 * the sliding animation, not for hiding the drawer */
 
-  bottom: -11em;
+  -webkit-transform: translate3d(0, 100px, 0);
+  transform: translate3d(0, 100px, 0);
   opacity: 0;
   -webkit-backface-visibility: hidden;
-  -webkit-transition-property: all;
-  transition-property: all;
-  -webkit-transition-duration: 0.2s;
-  transition-duration: 0.2s;
-  -webkit-transition-timing-function: ease;
-  transition-timing-function: ease;
+  -webkit-transition: -webkit-transform 0.25s, opacity 0.25s, visibility 0 
0.25s;
+  transition: transform 0.25s, opacity 0.25s, visibility 0 0.25s;
 }
 .animations .beta #mf-notification.visible,
 .animations .alpha #mf-notification.visible,
 .animations .beta .drawer.visible,
 .animations .alpha .drawer.visible {
+  -webkit-backface-visibility: hidden;
+  -webkit-transition: -webkit-transform 0.25s, opacity 0.25s;
+  transition: transform 0.25s, opacity 0.25s;
+  visibility: visible;
   opacity: 1;
-  /* -0.2em to avoid a weird glitch in some browsers where the popup moves
-                        * slightly when scrolling */
-
-  -webkit-transform: translate3d(0, -10.8em, 0);
-  transform: translate3d(0, -10.8em, 0);
+  -webkit-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
 }
 #mf-notification {
   font-size: 0.9em;
diff --git a/stylesheets/common/ui.css b/stylesheets/common/ui.css
index 54c3cf1..2df0653 100644
--- a/stylesheets/common/ui.css
+++ b/stylesheets/common/ui.css
@@ -198,7 +198,7 @@
 /* Left menu */
 #mw-mf-viewport {
   position: relative;
-  min-height: 100%;
+  height: 100%;
 }
 #mw-mf-page-center {
   width: 100%;
@@ -305,6 +305,7 @@
 body.navigation-enabled #mw-mf-viewport {
   margin-left: -12px;
   overflow: hidden;
+  height: auto !important;
 }
 body.navigation-enabled #mw-mf-page-center {
   position: absolute;
diff --git a/stylesheets/modules/mf-watchstar.css 
b/stylesheets/modules/mf-watchstar.css
index 4632992..18dde1f 100644
--- a/stylesheets/modules/mf-watchstar.css
+++ b/stylesheets/modules/mf-watchstar.css
@@ -5,12 +5,8 @@
 .animations .beta .watch-this-article,
 .animations .alpha .watch-this-article {
   -webkit-backface-visibility: hidden;
-  -webkit-transition-property: -webkit-transform;
-  transition-property: transform;
-  -webkit-transition-duration: 0.5s;
-  transition-duration: 0.5s;
-  -webkit-transition-timing-function: ease;
-  transition-timing-function: ease;
+  -webkit-transition: -webkit-transform 0.5s;
+  transition: transform 0.5s;
 }
 .animations .beta .watch-this-article.watched,
 .animations .alpha .watch-this-article.watched {
diff --git a/stylesheets/specials/mobilediff.css 
b/stylesheets/specials/mobilediff.css
index 24c1a93..e722b0a 100644
--- a/stylesheets/specials/mobilediff.css
+++ b/stylesheets/specials/mobilediff.css
@@ -156,7 +156,7 @@
   font-size: 0.9em;
   margin-top: 8px;
 }
-.supportsPositionFixed #mw-mf-diffview #mw-mf-userinfo {
+#mw-mf-diffview #mw-mf-userinfo {
   bottom: 0;
   left: 0;
   right: 0;
diff --git a/stylesheets/specials/uploads.css b/stylesheets/specials/uploads.css
index 955668b..9525699 100644
--- a/stylesheets/specials/uploads.css
+++ b/stylesheets/specials/uploads.css
@@ -128,12 +128,8 @@
 .animations .alpha .slideable .slider {
   left: 0;
   -webkit-backface-visibility: hidden;
-  -webkit-transition-property: all;
-  transition-property: all;
-  -webkit-transition-duration: 0.5s;
-  transition-duration: 0.5s;
-  -webkit-transition-timing-function: ease;
-  transition-timing-function: ease;
+  -webkit-transition: 0.5s;
+  transition: 0.5s;
 }
 .animations .beta .slideable .slider.slider-left,
 .animations .alpha .slideable .slider.slider-left {

-- 
To view, visit https://gerrit.wikimedia.org/r/71855
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I9aa603fae53c36184421c520e911f6e4b9ba5300
Gerrit-PatchSet: 4
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: JGonera <[email protected]>
Gerrit-Reviewer: Jdlrobson <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to