Bug 1444489 - Part VIII, Transition the visibility property instead of using transitionend event r=Gijs
authorTimothy Guan-tin Chien <timdream@gmail.com>
Fri, 16 Mar 2018 06:55:58 +0800
changeset 409386 99fc41ec7ce9
parent 409385 0f95b59a3e75
child 409387 becfb5f6388d
push id33686
push userapavel@mozilla.com
push dateThu, 22 Mar 2018 09:30:27 +0000
treeherdermozilla-central@f82d56c64966 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs
bugs1444489
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1444489 - Part VIII, Transition the visibility property instead of using transitionend event r=Gijs Fades out all the UIs by applying CSS transition on opacity and visibility. Stop relying on transitionend event to set the hidden state. This removes a source of intermittent failure and while making sure UIs are hidden. MozReview-Commit-ID: FR7JQn4eO3X
toolkit/content/tests/widgets/test_videocontrols_error.html
toolkit/content/widgets/videocontrols.xml
toolkit/themes/shared/media/videocontrols.css
--- a/toolkit/content/tests/widgets/test_videocontrols_error.html
+++ b/toolkit/content/tests/widgets/test_videocontrols_error.html
@@ -27,33 +27,31 @@
   });
 
   add_task(async function check_normal_status() {
     await new Promise(resolve => {
       video.src = "seek_with_sound.ogg";
       video.addEventListener("loadedmetadata", () => SimpleTest.executeSoon(resolve));
     });
 
-    // Wait for the fade out transition to complete in case the throbber
-    // shows up on slower platforms.
-    await SimpleTest.promiseWaitForCondition(() => statusOverlay.hidden,
+    await SimpleTest.promiseWaitForCondition(() => statusOverlay.hasAttribute("fadeout") || statusOverlay.hidden,
       "statusOverlay should not present without error");
 
     ok(!statusOverlay.hasAttribute("error"), "statusOverlay should not in error state");
     isnot(statusIcon.getAttribute("type"), "error", "should not show error icon");
   });
 
   add_task(async function invalid_source() {
     const errorType = "errorNoSource";
 
     await new Promise(resolve => {
       video.src = "invalid_source.ogg";
       video.addEventListener("error", () => SimpleTest.executeSoon(resolve));
     });
 
-    ok(!statusOverlay.hidden, `statusOverlay should show when ${errorType}`);
+    ok(!statusOverlay.hidden && !statusOverlay.hasAttribute("fadeout"), `statusOverlay should show when ${errorType}`);
     is(statusOverlay.getAttribute("error"), errorType, `statusOverlay should have correct error state: ${errorType}`);
     is(statusIcon.getAttribute("type"), "error", `should show error icon when ${errorType}`);
   });
 </script>
 </pre>
 </body>
 </html>
--- a/toolkit/content/widgets/videocontrols.xml
+++ b/toolkit/content/widgets/videocontrols.xml
@@ -1015,32 +1015,16 @@
           element.setAttribute("fadeout", true);
           if (element.classList.contains("controlBar") && !this.hasError() &&
               document.mozFullScreenElement == this.video) {
             this.controlsSpacer.setAttribute("hideCursor", true);
           }
         }
       },
 
-      onTransitionEnd(event) {
-        // Ignore events for things other than opacity changes.
-        if (event.propertyName != "opacity") {
-          return;
-        }
-
-        var element = event.originalTarget;
-
-        // Nothing to do when a fade *in* finishes.
-        if (!element.hasAttribute("fadeout")) {
-          return;
-        }
-
-        element.hidden = true;
-      },
-
       _triggeredByControls: false,
 
       startPlay() {
         this._triggeredByControls = true;
         this.hideClickToPlay();
         this.video.play();
       },
 
@@ -1769,17 +1753,16 @@
         // On touch videocontrols, tapping controlsSpacer should show/hide
         // the control bar, instead of playing the video or toggle fullscreen.
         if (!this.videocontrols.isTouchControls) {
           addListener(this.controlsSpacer, "click", this.clickToPlayClickHandler);
           addListener(this.controlsSpacer, "dblclick", this.toggleFullscreen);
         }
 
         addListener(this.videocontrols, "resizevideocontrols", this.adjustControlSize);
-        addListener(this.videocontrols, "transitionend", this.onTransitionEnd);
         addListener(this.controlBar, "transitionend", this.onControlBarTransitioned);
         // See comment at onFullscreenChange on bug 718107.
         // addListener(this.video.ownerDocument, "fullscreenchange", this.onFullscreenChange);
         addListener(this.video, "keypress", this.keyHandler, {capture: true});
         // Prevent any click event within media controls from dispatching through to video.
         addListener(this.videocontrols, "click", function(event) {
           event.stopPropagation();
         }, {mozSystemGroup: false});
--- a/toolkit/themes/shared/media/videocontrols.css
+++ b/toolkit/themes/shared/media/videocontrols.css
@@ -437,60 +437,55 @@ audio > xul|videocontrols {
 
 .controlsSpacerStack:hover > .clickToPlay,
 .clickToPlay:hover {
   opacity: 0.55;
 }
 
 .controlsSpacerStack:hover > .clickToPlay[fadeout] {
   opacity: 0;
+  visibility: hidden;
 }
 
 .controlBar[fullscreen-unavailable] .fullscreenButton {
   display: none;
 }
 
 /* CSS Transitions */
-.clickToPlay {
-  transition-property: transform, opacity;
-  transition-duration: 400ms, 400ms;
-}
-
-.controlsSpacer[fadeout] {
-  opacity: 0;
+.clickToPlay:not([immediate]) {
+  transition-property: transform, opacity, visibility;
+  transition-duration: 400ms, 400ms, 400ms;
 }
 
 .clickToPlay[fadeout] {
   transform: scale(3);
   opacity: 0;
+  visibility: hidden;
+}
+
+.controlBar:not([immediate]) {
+  transition-property: opacity, visibility;
+  transition-duration: 200ms, 200ms;
 }
 
-.clickToPlay[fadeout][immediate] {
-  transition-property: opacity, background-size;
-  transition-duration: 0s, 0s;
-}
-.controlBar:not([immediate]) {
-  transition-property: opacity;
-  transition-duration: 200ms;
-}
 .controlBar[fadeout] {
   opacity: 0;
-}
-.volumeStack:not([immediate]) {
-  transition-property: opacity, margin-top;
-  transition-duration: 200ms, 200ms;
+  visibility: hidden;
 }
+
 .statusOverlay:not([immediate]) {
-  transition-property: opacity;
-  transition-duration: 300ms;
-  transition-delay: 750ms;
+  transition-property: opacity, visibility;
+  transition-duration: 300ms, 300ms;
+  transition-delay: 750ms, 750ms;
 }
+
 .statusOverlay[fadeout],
 .statusOverlay[error] + .controlsOverlay > .controlsSpacerStack {
   opacity: 0;
+  visibility: hidden;
 }
 
 /* Error description formatting */
 .errorLabel {
   padding: 0 10px;
   text-align: center;
   font: message-box;
   font-size: 14px;