Changeset 202679 in webkit


Ignore:
Timestamp:
Jun 30, 2016 8:09:35 AM (8 years ago)
Author:
commit-queue@webkit.org
Message:

[iOS] Media controls are too cramped with small video
https://bugs.webkit.org/show_bug.cgi?id=158815
<rdar://problem/26824238>

Patch by Antoine Quint <Antoine Quint> on 2016-06-30
Reviewed by Eric Carlson.

Source/WebCore:

In updateLayoutForDisplayedWidth(), we try to ensure a minimum width is guaranteed
for the progress indicator. However, we were not accounting for the width used by
the current and remaining time labels on either side of it, so we would incorrectly
conclude that we were guaranteeing the minimum time and yield incorrect layouts since
we were trying to fit more buttons than we had room for.

In order to correctly compute the available width for the progress indicator, we now
have clones of the current and remaining time labels, hidden from video and VoiceOver,
that we update along with the originals. The same styles apply to both clones and
originals, so we may measure the clones to determine the space used by the time labels.
The reason we need to use clones is that if the time labels had previously been hidden
from view, precisely because there was not enough space to display them along with the
progress indicator, then trying to obtain metrics from them would yield 0 since they had
"display: none" styles applied. In order to avoid extra layouts and possible flashing, we
use the clones so that we never have to toggle the "display" property of the originals
just to obtain their measurements.

As a result of this change, we adjust the constant used to set the minimum required
width available to display the progress indicator after all other essential controls
and labels have been measured. That constant used to account for the width of the
time labels, and this is no longer correct.

Test: media/video-controls-drop-and-restore-timeline.html

  • Modules/mediacontrols/mediaControlsApple.css:

(::-webkit-media-controls-time-remaining-display.clone):

  • Modules/mediacontrols/mediaControlsApple.js:

(Controller):
(Controller.prototype.createTimeClones):
(Controller.prototype.removeTimeClass):
(Controller.prototype.addTimeClass):
(Controller.prototype.updateDuration):
(Controller.prototype.updateLayoutForDisplayedWidth):
(Controller.prototype.updateTime):
(Controller.prototype.updateControlsWhileScrubbing):

  • Modules/mediacontrols/mediaControlsiOS.css:

(::-webkit-media-controls-time-remaining-display.clone):

  • Modules/mediacontrols/mediaControlsiOS.js:

LayoutTests:

Adjust the output of this test to account for the time label clones and add a new test.

  • media/video-controls-drop-and-restore-timeline-expected.txt: Added.
  • media/video-controls-drop-and-restore-timeline.html: Added.
  • platform/mac-yosemite/http/tests/media/hls/video-controls-live-stream-expected.txt:
  • platform/mac/http/tests/media/hls/video-controls-live-stream-expected.txt:
Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r202672 r202679  
     12016-06-30  Antoine Quint  <graouts@apple.com>
     2
     3        [iOS] Media controls are too cramped with small video
     4        https://bugs.webkit.org/show_bug.cgi?id=158815
     5        <rdar://problem/26824238>
     6
     7        Reviewed by Eric Carlson.
     8
     9        Adjust the output of this test to account for the time label clones and add a new test.
     10
     11        * media/video-controls-drop-and-restore-timeline-expected.txt: Added.
     12        * media/video-controls-drop-and-restore-timeline.html: Added.
     13        * platform/mac-yosemite/http/tests/media/hls/video-controls-live-stream-expected.txt:
     14        * platform/mac/http/tests/media/hls/video-controls-live-stream-expected.txt:
     15
    1162016-06-29  Benjamin Poulain  <bpoulain@apple.com>
    217
  • trunk/LayoutTests/platform/mac-yosemite/http/tests/media/hls/video-controls-live-stream-expected.txt

    r202514 r202679  
    55-webkit-media-text-track-container: classes: [hidden]
    66-webkit-media-show-controls: classes: []
     7-webkit-media-controls-current-time-display: classes: [clone six-digit-time]
     8-webkit-media-controls-time-remaining-display: classes: [clone six-digit-time]
    79-webkit-media-controls-wireless-playback-status: classes: [hidden]
    810-webkit-media-controls-wireless-playback-text: classes: []
  • trunk/LayoutTests/platform/mac/http/tests/media/hls/video-controls-live-stream-expected.txt

    r202514 r202679  
    55-webkit-media-text-track-container: classes: [hidden]
    66-webkit-media-show-controls: classes: []
     7-webkit-media-controls-current-time-display: classes: [clone six-digit-time]
     8-webkit-media-controls-time-remaining-display: classes: [clone six-digit-time]
    79-webkit-media-controls-wireless-playback-status: classes: [hidden]
    810-webkit-media-controls-wireless-playback-text: classes: []
  • trunk/Source/WebCore/ChangeLog

    r202678 r202679  
     12016-06-30  Antoine Quint  <graouts@apple.com>
     2
     3        [iOS] Media controls are too cramped with small video
     4        https://bugs.webkit.org/show_bug.cgi?id=158815
     5        <rdar://problem/26824238>
     6
     7        Reviewed by Eric Carlson.
     8
     9        In updateLayoutForDisplayedWidth(), we try to ensure a minimum width is guaranteed
     10        for the progress indicator. However, we were not accounting for the width used by
     11        the current and remaining time labels on either side of it, so we would incorrectly
     12        conclude that we were guaranteeing the minimum time and yield incorrect layouts since
     13        we were trying to fit more buttons than we had room for.
     14
     15        In order to correctly compute the available width for the progress indicator, we now
     16        have clones of the current and remaining time labels, hidden from video and VoiceOver,
     17        that we update along with the originals. The same styles apply to both clones and
     18        originals, so we may measure the clones to determine the space used by the time labels.
     19        The reason we need to use clones is that if the time labels had previously been hidden
     20        from view, precisely because there was not enough space to display them along with the
     21        progress indicator, then trying to obtain metrics from them would yield 0 since they had
     22        "display: none" styles applied. In order to avoid extra layouts and possible flashing, we
     23        use the clones so that we never have to toggle the "display" property of the originals
     24        just to obtain their measurements.
     25
     26        As a result of this change, we adjust the constant used to set the minimum required
     27        width available to display the progress indicator after all other essential controls
     28        and labels have been measured. That constant used to account for the width of the
     29        time labels, and this is no longer correct.
     30
     31        Test: media/video-controls-drop-and-restore-timeline.html
     32
     33        * Modules/mediacontrols/mediaControlsApple.css:
     34        (::-webkit-media-controls-time-remaining-display.clone):
     35        * Modules/mediacontrols/mediaControlsApple.js:
     36        (Controller):
     37        (Controller.prototype.createTimeClones):
     38        (Controller.prototype.removeTimeClass):
     39        (Controller.prototype.addTimeClass):
     40        (Controller.prototype.updateDuration):
     41        (Controller.prototype.updateLayoutForDisplayedWidth):
     42        (Controller.prototype.updateTime):
     43        (Controller.prototype.updateControlsWhileScrubbing):
     44        * Modules/mediacontrols/mediaControlsiOS.css:
     45        (::-webkit-media-controls-time-remaining-display.clone):
     46        * Modules/mediacontrols/mediaControlsiOS.js:
     47
    1482016-06-30  Eric Carlson  <eric.carlson@apple.com>
    249
  • trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.css

    r202514 r202679  
    11431143    margin-left: 0px;
    11441144}
     1145
     1146/* Time display clones that we use in updateLayoutForDisplayedWidth(). */
     1147::-webkit-media-controls-current-time-display.clone,
     1148::-webkit-media-controls-time-remaining-display.clone {
     1149    position: absolute;
     1150    display: inline;
     1151    top: 100%;
     1152    mix-blend-mode: normal;
     1153}
  • trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js

    r202514 r202679  
    2626    this.createBase();
    2727    this.createControls();
     28    this.createTimeClones();
    2829    this.updateBase();
    2930    this.updateControls();
     
    133134        down: 40
    134135    },
    135     MinimumTimelineWidth: 150,
     136    MinimumTimelineWidth: 100,
    136137    ButtonWidth: 32,
    137138
     
    529530        if (!Controller.gSimulateWirelessPlaybackTarget)
    530531            wirelessTargetPicker.classList.add(this.ClassNames.hidden);
     532    },
     533
     534    createTimeClones: function()
     535    {
     536        var currentTimeClone = this.currentTimeClone = document.createElement('div');
     537        currentTimeClone.setAttribute('pseudo', '-webkit-media-controls-current-time-display');
     538        currentTimeClone.setAttribute('aria-hidden', 'true');
     539        currentTimeClone.classList.add('clone');
     540        this.base.appendChild(currentTimeClone);
     541
     542        var remainingTimeClone = this.remainingTimeClone = document.createElement('div');
     543        remainingTimeClone.setAttribute('pseudo', '-webkit-media-controls-time-remaining-display');
     544        remainingTimeClone.setAttribute('aria-hidden', 'true');
     545        remainingTimeClone.classList.add('clone');
     546        this.base.appendChild(remainingTimeClone);
    531547    },
    532548
     
    12791295        this.setIsLive(duration === Number.POSITIVE_INFINITY);
    12801296
     1297        var timeControls = [this.controls.currentTime, this.controls.remainingTime, this.currentTimeClone, this.remainingTimeClone];
     1298
     1299        function removeTimeClass(className) {
     1300            for (let element of timeControls)
     1301                element.classList.remove(className);
     1302        }
     1303
     1304        function addTimeClass(className) {
     1305            for (let element of timeControls)
     1306                element.classList.add(className);
     1307        }
     1308
    12811309        // Reset existing style.
    1282         this.controls.currentTime.classList.remove(this.ClassNames.threeDigitTime);
    1283         this.controls.currentTime.classList.remove(this.ClassNames.fourDigitTime);
    1284         this.controls.currentTime.classList.remove(this.ClassNames.fiveDigitTime);
    1285         this.controls.currentTime.classList.remove(this.ClassNames.sixDigitTime);
    1286         this.controls.remainingTime.classList.remove(this.ClassNames.threeDigitTime);
    1287         this.controls.remainingTime.classList.remove(this.ClassNames.fourDigitTime);
    1288         this.controls.remainingTime.classList.remove(this.ClassNames.fiveDigitTime);
    1289         this.controls.remainingTime.classList.remove(this.ClassNames.sixDigitTime);
    1290 
    1291         if (duration >= 60*60*10) {
    1292             this.controls.currentTime.classList.add(this.ClassNames.sixDigitTime);
    1293             this.controls.remainingTime.classList.add(this.ClassNames.sixDigitTime);
    1294         } else if (duration >= 60*60) {
    1295             this.controls.currentTime.classList.add(this.ClassNames.fiveDigitTime);
    1296             this.controls.remainingTime.classList.add(this.ClassNames.fiveDigitTime);
    1297         } else if (duration >= 60*10) {
    1298             this.controls.currentTime.classList.add(this.ClassNames.fourDigitTime);
    1299             this.controls.remainingTime.classList.add(this.ClassNames.fourDigitTime);
    1300         } else {
    1301             this.controls.currentTime.classList.add(this.ClassNames.threeDigitTime);
    1302             this.controls.remainingTime.classList.add(this.ClassNames.threeDigitTime);
    1303         }
     1310        removeTimeClass(this.ClassNames.threeDigitTime);
     1311        removeTimeClass(this.ClassNames.fourDigitTime);
     1312        removeTimeClass(this.ClassNames.fiveDigitTime);
     1313        removeTimeClass(this.ClassNames.sixDigitTime);
     1314
     1315        if (duration >= 60*60*10)
     1316            addTimeClass(this.ClassNames.sixDigitTime);
     1317        else if (duration >= 60*60)
     1318            addTimeClass(this.ClassNames.fiveDigitTime);
     1319        else if (duration >= 60*10)
     1320            addTimeClass(this.ClassNames.fourDigitTime);
     1321        else
     1322            addTimeClass(this.ClassNames.threeDigitTime);
    13041323    },
    13051324
     
    16271646        var visibleButtonWidth = this.ButtonWidth * visibleButtons.length;
    16281647
     1648        var currentTimeWidth = this.currentTimeClone.getBoundingClientRect().width;
     1649        var remainingTimeWidth = this.remainingTimeClone.getBoundingClientRect().width;
     1650
    16291651        // Check if there is enough room for the scrubber.
    1630         var shouldDropTimeline = (visibleWidth - visibleButtonWidth) < this.MinimumTimelineWidth;
     1652        var shouldDropTimeline = (visibleWidth - visibleButtonWidth - currentTimeWidth - remainingTimeWidth) < this.MinimumTimelineWidth;
    16311653        this.controls.timeline.classList.toggle(this.ClassNames.dropped, shouldDropTimeline);
    16321654        this.controls.currentTime.classList.toggle(this.ClassNames.dropped, shouldDropTimeline);
     
    16821704        var currentTime = this.video.currentTime;
    16831705        var timeRemaining = currentTime - this.video.duration;
    1684         this.controls.currentTime.innerText = this.formatTime(currentTime);
     1706        this.currentTimeClone.innerText = this.controls.currentTime.innerText = this.formatTime(currentTime);
    16851707        this.controls.timeline.value = this.video.currentTime;
    1686         this.controls.remainingTime.innerText = this.formatTime(timeRemaining);
     1708        this.remainingTimeClone.innerText = this.controls.remainingTime.innerText = this.formatTime(timeRemaining);
    16871709    },
    16881710   
     
    16941716        var currentTime = (this.controls.timeline.value / this.controls.timeline.max) * this.video.duration;
    16951717        var timeRemaining = currentTime - this.video.duration;
    1696         this.controls.currentTime.innerText = this.formatTime(currentTime);
    1697         this.controls.remainingTime.innerText = this.formatTime(timeRemaining);
     1718        this.currentTimeClone.innerText = this.controls.currentTime.innerText = this.formatTime(currentTime);
     1719        this.remainingTimeClone.innerText = this.controls.remainingTime.innerText = this.formatTime(timeRemaining);
    16981720        this.drawTimelineBackground();
    16991721    },
  • trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.css

    r202514 r202679  
    724724}
    725725
     726/* Time display clones that we use in updateLayoutForDisplayedWidth(). */
     727::-webkit-media-controls-current-time-display.clone,
     728::-webkit-media-controls-time-remaining-display.clone {
     729    position: absolute;
     730    display: inline;
     731    top: 100%;
     732    mix-blend-mode: normal;
     733}
  • trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.js

    r202514 r202679  
    2828ControllerIOS.prototype = {
    2929    /* Constants */
    30     MinimumTimelineWidth: 200,
     30    MinimumTimelineWidth: 150,
    3131    ButtonWidth: 42,
    3232
Note: See TracChangeset for help on using the changeset viewer.