Changeset 202505 in webkit


Ignore:
Timestamp:
Jun 27, 2016 12:06:45 PM (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-27
Reviewed by Dean Jackson.

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

    r202498 r202505  
     12016-06-27  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 Dean Jackson.
     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-27  Joseph Pecoraro  <pecoraro@apple.com>
    217
  • trunk/LayoutTests/platform/mac-yosemite/http/tests/media/hls/video-controls-live-stream-expected.txt

    r202183 r202505  
    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

    r202183 r202505  
    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

    r202499 r202505  
     12016-06-27  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 Dean Jackson.
     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-27  Anders Carlsson  <andersca@apple.com>
    249
  • trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.css

    r202274 r202505  
    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

    r202274 r202505  
    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
     
    526527        if (!Controller.gSimulateWirelessPlaybackTarget)
    527528            wirelessTargetPicker.classList.add(this.ClassNames.hidden);
     529    },
     530
     531    createTimeClones: function()
     532    {
     533        var currentTimeClone = this.currentTimeClone = document.createElement('div');
     534        currentTimeClone.setAttribute('pseudo', '-webkit-media-controls-current-time-display');
     535        currentTimeClone.setAttribute('aria-hidden', 'true');
     536        currentTimeClone.classList.add('clone');
     537        this.base.appendChild(currentTimeClone);
     538
     539        var remainingTimeClone = this.remainingTimeClone = document.createElement('div');
     540        remainingTimeClone.setAttribute('pseudo', '-webkit-media-controls-time-remaining-display');
     541        remainingTimeClone.setAttribute('aria-hidden', 'true');
     542        remainingTimeClone.classList.add('clone');
     543        this.base.appendChild(remainingTimeClone);
    528544    },
    529545
     
    12761292        this.setIsLive(duration === Number.POSITIVE_INFINITY);
    12771293
     1294        var timeControls = [this.controls.currentTime, this.controls.remainingTime, this.currentTimeClone, this.remainingTimeClone];
     1295
     1296        function removeTimeClass(className) {
     1297            for (let element of timeControls)
     1298                element.classList.remove(className);
     1299        }
     1300
     1301        function addTimeClass(className) {
     1302            for (let element of timeControls)
     1303                element.classList.add(className);
     1304        }
     1305
    12781306        // Reset existing style.
    1279         this.controls.currentTime.classList.remove(this.ClassNames.threeDigitTime);
    1280         this.controls.currentTime.classList.remove(this.ClassNames.fourDigitTime);
    1281         this.controls.currentTime.classList.remove(this.ClassNames.fiveDigitTime);
    1282         this.controls.currentTime.classList.remove(this.ClassNames.sixDigitTime);
    1283         this.controls.remainingTime.classList.remove(this.ClassNames.threeDigitTime);
    1284         this.controls.remainingTime.classList.remove(this.ClassNames.fourDigitTime);
    1285         this.controls.remainingTime.classList.remove(this.ClassNames.fiveDigitTime);
    1286         this.controls.remainingTime.classList.remove(this.ClassNames.sixDigitTime);
    1287 
    1288         if (duration >= 60*60*10) {
    1289             this.controls.currentTime.classList.add(this.ClassNames.sixDigitTime);
    1290             this.controls.remainingTime.classList.add(this.ClassNames.sixDigitTime);
    1291         } else if (duration >= 60*60) {
    1292             this.controls.currentTime.classList.add(this.ClassNames.fiveDigitTime);
    1293             this.controls.remainingTime.classList.add(this.ClassNames.fiveDigitTime);
    1294         } else if (duration >= 60*10) {
    1295             this.controls.currentTime.classList.add(this.ClassNames.fourDigitTime);
    1296             this.controls.remainingTime.classList.add(this.ClassNames.fourDigitTime);
    1297         } else {
    1298             this.controls.currentTime.classList.add(this.ClassNames.threeDigitTime);
    1299             this.controls.remainingTime.classList.add(this.ClassNames.threeDigitTime);
    1300         }
     1307        removeTimeClass(this.ClassNames.threeDigitTime);
     1308        removeTimeClass(this.ClassNames.fourDigitTime);
     1309        removeTimeClass(this.ClassNames.fiveDigitTime);
     1310        removeTimeClass(this.ClassNames.sixDigitTime);
     1311
     1312        if (duration >= 60*60*10)
     1313            addTimeClass(this.ClassNames.sixDigitTime);
     1314        else if (duration >= 60*60)
     1315            addTimeClass(this.ClassNames.fiveDigitTime);
     1316        else if (duration >= 60*10)
     1317            addTimeClass(this.ClassNames.fourDigitTime);
     1318        else
     1319            addTimeClass(this.ClassNames.threeDigitTime);
    13011320    },
    13021321
     
    16241643        var visibleButtonWidth = this.ButtonWidth * visibleButtons.length;
    16251644
     1645        var currentTimeWidth = this.currentTimeClone.getBoundingClientRect().width;
     1646        var remainingTimeWidth = this.remainingTimeClone.getBoundingClientRect().width;
     1647
    16261648        // Check if there is enough room for the scrubber.
    1627         var shouldDropTimeline = (visibleWidth - visibleButtonWidth) < this.MinimumTimelineWidth;
     1649        var shouldDropTimeline = (visibleWidth - visibleButtonWidth - currentTimeWidth - remainingTimeWidth) < this.MinimumTimelineWidth;
    16281650        this.controls.timeline.classList.toggle(this.ClassNames.dropped, shouldDropTimeline);
    16291651        this.controls.currentTime.classList.toggle(this.ClassNames.dropped, shouldDropTimeline);
     
    16791701        var currentTime = this.video.currentTime;
    16801702        var timeRemaining = currentTime - this.video.duration;
    1681         this.controls.currentTime.innerText = this.formatTime(currentTime);
     1703        this.currentTimeClone.innerText = this.controls.currentTime.innerText = this.formatTime(currentTime);
    16821704        this.controls.timeline.value = this.video.currentTime;
    1683         this.controls.remainingTime.innerText = this.formatTime(timeRemaining);
     1705        this.remainingTimeClone.innerText = this.controls.remainingTime.innerText = this.formatTime(timeRemaining);
    16841706    },
    16851707   
     
    16911713        var currentTime = (this.controls.timeline.value / this.controls.timeline.max) * this.video.duration;
    16921714        var timeRemaining = currentTime - this.video.duration;
    1693         this.controls.currentTime.innerText = this.formatTime(currentTime);
    1694         this.controls.remainingTime.innerText = this.formatTime(timeRemaining);
     1715        this.currentTimeClone.innerText = this.controls.currentTime.innerText = this.formatTime(currentTime);
     1716        this.remainingTimeClone.innerText = this.controls.remainingTime.innerText = this.formatTime(timeRemaining);
    16951717        this.drawTimelineBackground();
    16961718    },
  • trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.css

    r201450 r202505  
    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

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