Bug 462117 - Reducing the number of visible controls when the video is too small. r=dolske
☠☠ backed out by ef520743354a ☠ ☠
authorJared Wein <jwein@mozilla.com>
Thu, 22 Sep 2011 16:19:52 -0700
changeset 77390 49678dad20f0128cfb4748d702496c06edb88de9
parent 77389 bf900e375add310511e301f9b86c061b13968f5a
child 77391 ef520743354a661a7089db386a8e607bf17b7019
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersdolske
bugs462117
milestone9.0a1
Bug 462117 - Reducing the number of visible controls when the video is too small. r=dolske
toolkit/content/widgets/videocontrols.css
toolkit/content/widgets/videocontrols.xml
--- a/toolkit/content/widgets/videocontrols.css
+++ b/toolkit/content/widgets/videocontrols.css
@@ -48,8 +48,23 @@
 .statusOverlay:not([immediate]) {
   -moz-transition-property: opacity;
   -moz-transition-duration: 1ms;
   -moz-transition-delay: 750ms;
 }
 .statusOverlay[fadeout] {
   opacity: 0;
 }
+
+.controlBar[size="hidden"],
+.controlBar[size="small"] .durationBox,
+.controlBar[size="small"] .durationLabel,
+.controlBar[size="small"] .positionLabel {
+  visibility: collapse;
+}
+
+.controlBar[size="small"] .scrubberStack {
+  visibility: hidden;
+}
+
+.controlBar[size="small"] .scrubberStack > * {
+  visibility: hidden;
+}
--- a/toolkit/content/widgets/videocontrols.xml
+++ b/toolkit/content/widgets/videocontrols.xml
@@ -338,16 +338,27 @@
                     // Set the current status icon.
                     if (this.video.error || this.video.networkState == this.video.NETWORK_NO_SOURCE) {
                         this.statusIcon.setAttribute("type", "error");
                         this.setupStatusFader(true);
                     } else {
                         this.statusIcon.setAttribute("type", "throbber");
                         this.setupStatusFader();
                     }
+
+                    // An event handler for |onresize| should be added when bug 227495 is fixed.
+                    let controlBarWasHidden = this.controlBar.getAttribute("hidden") == "true";
+                    this.controlBar.removeAttribute("hidden");
+                    this._playButtonWidth = this.playButton.clientWidth;
+                    this._durationLabelWidth = this.durationLabel.clientWidth;
+                    this._muteButtonWidth = this.muteButton.clientWidth;
+                    this._controlBarHeight = this.controlBar.clientHeight;
+                    if (controlBarWasHidden)
+                      this.controlBar.setAttribute("hidden", "true");
+                    this.adjustControlSize();
                 },
 
                 get dynamicControls() {
                     // Don't fade controls for <audio> elements.
                     var enabled = !this.isAudioOnly;
 
                     // Allow tests to explicitly suppress the fading of controls.
                     if (this.video.hasAttribute("mozNoDynamicControls"))
@@ -395,16 +406,17 @@
                             this.setupStatusFader();
                             break;
                         case "volumechange":
                             var volume = this.video.muted ? 0 : Math.round(this.video.volume * 100);
                             this.setMuteButtonState(this.video.muted);
                             this.volumeControl.value = volume;
                             break;
                         case "loadedmetadata":
+                            this.adjustControlSize();
                             // If a <video> doesn't have any video data, treat it as <audio>
                             // and show the controls (they won't fade back out)
                             if (this.video instanceof HTMLVideoElement &&
                                 (this.video.videoWidth == 0 || this.video.videoHeight == 0)) {
                                 this.isAudioOnly = true;
                                 this.startFadeIn(this.controlBar);
                             }
                             this.showDuration(Math.round(this.video.duration * 1000));
@@ -649,16 +661,19 @@
 
                     // Suppress fading out the controls until the video has rendered
                     // its first frame. But since autoplay videos start off with no
                     // controls, let them fade-out so the controls don't get stuck on.
                     if (!this.firstFrameShown && !isMouseOver &&
                         !(this.video.autoplay && this.video.mozAutoplayEnabled))
                         return;
 
+                    if (!isMouseOver)
+                        this.adjustControlSize();
+
                     this.startFade(this.controlBar, isMouseOver);
                 },
 
                 startFadeIn : function (element, immediate) {
                     this.startFade(element, true, immediate);
                 },
 
                 startFadeOut : function (element, immediate) {
@@ -856,16 +871,44 @@
                     return isDescendant(event.target) && isDescendant(event.relatedTarget);
                 },
 
                 log : function (msg) {
                     if (this.debug)
                         dump("videoctl: " + msg + "\n");
                 },
 
+                _playButtonWidth : 0,
+                _durationLabelWidth : 0,
+                _muteButtonWidth : 0,
+                _controlBarHeight : 0,
+                adjustControlSize : function adjustControlSize() {
+                    let videoHeight = this.video.clientHeight;
+                    let videoWidth = this.video.clientWidth;
+
+                    // The scrubber has |flex=1|, therefore |minScrubberWidth|
+                    // was generated by empirical testing.
+                    let minScrubberWidth = 25;
+                    let minWidthAllControls = this._playButtonWidth +
+                                              minScrubberWidth +
+                                              this._durationLabelWidth +
+                                              this._muteButtonWidth;
+                    let minHeightForControlBar = this._controlBarHeight;
+                    let minWidthOnlyPlayPause = this._playButtonWidth + this._muteButtonWidth;
+
+                    let size = "normal";
+                    if (videoHeight < minHeightForControlBar)
+                        size = "hidden";
+                    else if (videoWidth < minWidthOnlyPlayPause)
+                        size = "hidden";
+                    else if (videoWidth < minWidthAllControls)
+                        size = "small";
+                    this.controlBar.setAttribute("size", size);
+                },
+
                 init : function (binding) {
                     this.video = binding.parentNode;
                     this.videocontrols = binding;
                     this.isAudioOnly = (this.video instanceof HTMLAudioElement);
 
                     this.statusIcon    = document.getAnonymousElementByAttribute(binding, "class", "statusIcon");
                     this.controlBar    = document.getAnonymousElementByAttribute(binding, "class", "controlBar");
                     this.playButton    = document.getAnonymousElementByAttribute(binding, "class", "playButton");
@@ -874,17 +917,17 @@
                     this.volumeStack   = document.getAnonymousElementByAttribute(binding, "class", "volumeStack");
                     this.progressBar   = document.getAnonymousElementByAttribute(binding, "class", "progressBar");
                     this.bufferBar     = document.getAnonymousElementByAttribute(binding, "class", "bufferBar");
                     this.scrubber      = document.getAnonymousElementByAttribute(binding, "class", "scrubber");
                     this.scrubberThumb = document.getAnonymousElementByAttribute(this.scrubber, "class", "scale-thumb");
                     this.durationLabel = document.getAnonymousElementByAttribute(binding, "class", "durationLabel");
                     this.positionLabel = document.getAnonymousElementByAttribute(binding, "class", "positionLabel");
                     this.statusOverlay = document.getAnonymousElementByAttribute(binding, "class", "statusOverlay");
-                    this.controlsSpacer = document.getAnonymousElementByAttribute(binding, "class", "controlsSpacer")
+                    this.controlsSpacer = document.getAnonymousElementByAttribute(binding, "class", "controlsSpacer");
 
                     this.setupInitialState();
 
                     // videocontrols.css hides the control bar by default, because if script
                     // is disabled our binding's script is disabled too (bug 449358). Thus,
                     // the controls are broken and we don't want them shown. But if script is
                     // enabled, the code here will run and can explicitly unhide the controls.
                     //