Bug 1444489 - Part VIII, Transition the visibility property instead of using transitionend event draft
authorTimothy Guan-tin Chien <timdream@gmail.com>
Fri, 16 Mar 2018 06:55:58 +0800
changeset 770607 93e4192d67d4
parent 770606 365b6076f7ff
push id103447
push usertimdream@gmail.com
push dateWed, 21 Mar 2018 15:57:15 +0000
bugs1444489
milestone61.0a1
Bug 1444489 - Part VIII, Transition the visibility property instead of using transitionend event 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;