| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. | 3 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 #include "core/html/track/TextTrackContainer.h" | 35 #include "core/html/track/TextTrackContainer.h" |
| 36 #include "core/layout/LayoutTheme.h" | 36 #include "core/layout/LayoutTheme.h" |
| 37 #include "platform/EventDispatchForbiddenScope.h" | 37 #include "platform/EventDispatchForbiddenScope.h" |
| 38 | 38 |
| 39 namespace blink { | 39 namespace blink { |
| 40 | 40 |
| 41 // If you change this value, then also update the corresponding value in | 41 // If you change this value, then also update the corresponding value in |
| 42 // LayoutTests/media/media-controls.js. | 42 // LayoutTests/media/media-controls.js. |
| 43 static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3; | 43 static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3; |
| 44 | 44 |
| 45 // We only want to show the overflow menu if it contains at least two buttons |
| 46 static const int minOverflowMenuControlElementsNum = 2; |
| 47 |
| 45 static bool shouldShowFullscreenButton(const HTMLMediaElement& mediaElement) | 48 static bool shouldShowFullscreenButton(const HTMLMediaElement& mediaElement) |
| 46 { | 49 { |
| 47 // Unconditionally allow the user to exit fullscreen if we are in it | 50 // Unconditionally allow the user to exit fullscreen if we are in it |
| 48 // now. Especially on android, when we might not yet know if | 51 // now. Especially on android, when we might not yet know if |
| 49 // fullscreen is supported, we sometimes guess incorrectly and show | 52 // fullscreen is supported, we sometimes guess incorrectly and show |
| 50 // the button earlier, and we don't want to remove it here if the | 53 // the button earlier, and we don't want to remove it here if the |
| 51 // user chose to enter fullscreen. crbug.com/500732 . | 54 // user chose to enter fullscreen. crbug.com/500732 . |
| 52 if (mediaElement.isFullscreen()) | 55 if (mediaElement.isFullscreen()) |
| 53 return true; | 56 return true; |
| 54 | 57 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 , m_enclosure(nullptr) | 113 , m_enclosure(nullptr) |
| 111 , m_panel(nullptr) | 114 , m_panel(nullptr) |
| 112 , m_playButton(nullptr) | 115 , m_playButton(nullptr) |
| 113 , m_timeline(nullptr) | 116 , m_timeline(nullptr) |
| 114 , m_currentTimeDisplay(nullptr) | 117 , m_currentTimeDisplay(nullptr) |
| 115 , m_durationDisplay(nullptr) | 118 , m_durationDisplay(nullptr) |
| 116 , m_muteButton(nullptr) | 119 , m_muteButton(nullptr) |
| 117 , m_volumeSlider(nullptr) | 120 , m_volumeSlider(nullptr) |
| 118 , m_toggleClosedCaptionsButton(nullptr) | 121 , m_toggleClosedCaptionsButton(nullptr) |
| 119 , m_textTrackList(nullptr) | 122 , m_textTrackList(nullptr) |
| 123 , m_overflowList(nullptr) |
| 124 , m_muteOverflowButton(nullptr) |
| 125 , m_castOverflowButton(nullptr) |
| 126 , m_closedCaptionsOverflowButton(nullptr) |
| 127 , m_fullscreenOverflowButton(nullptr) |
| 120 , m_castButton(nullptr) | 128 , m_castButton(nullptr) |
| 121 , m_fullScreenButton(nullptr) | 129 , m_fullScreenButton(nullptr) |
| 122 , m_hideMediaControlsTimer(this, &MediaControls::hideMediaControlsTimerFired
) | 130 , m_hideMediaControlsTimer(this, &MediaControls::hideMediaControlsTimerFired
) |
| 123 , m_hideTimerBehaviorFlags(IgnoreNone) | 131 , m_hideTimerBehaviorFlags(IgnoreNone) |
| 124 , m_isMouseOverControls(false) | 132 , m_isMouseOverControls(false) |
| 125 , m_isPausedForScrubbing(false) | 133 , m_isPausedForScrubbing(false) |
| 126 , m_panelWidthChangedTimer(this, &MediaControls::panelWidthChangedTimerFired
) | 134 , m_panelWidthChangedTimer(this, &MediaControls::panelWidthChangedTimerFired
) |
| 127 , m_panelWidth(0) | 135 , m_panelWidth(0) |
| 128 , m_allowHiddenVolumeControls(RuntimeEnabledFeatures::newMediaPlaybackUiEnab
led()) | 136 , m_allowHiddenVolumeControls(RuntimeEnabledFeatures::newMediaPlaybackUiEnab
led()) |
| 129 { | 137 { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 | 243 |
| 236 m_panel = panel; | 244 m_panel = panel; |
| 237 enclosure->appendChild(panel); | 245 enclosure->appendChild(panel); |
| 238 | 246 |
| 239 m_enclosure = enclosure; | 247 m_enclosure = enclosure; |
| 240 appendChild(enclosure); | 248 appendChild(enclosure); |
| 241 | 249 |
| 242 MediaControlTextTrackListElement* textTrackList = MediaControlTextTrackListE
lement::create(*this); | 250 MediaControlTextTrackListElement* textTrackList = MediaControlTextTrackListE
lement::create(*this); |
| 243 m_textTrackList = textTrackList; | 251 m_textTrackList = textTrackList; |
| 244 appendChild(textTrackList); | 252 appendChild(textTrackList); |
| 253 |
| 254 MediaControlOverflowMenu* overflowMenu = MediaControlOverflowMenu::create(*t
his); |
| 255 m_overflowMenu = overflowMenu; |
| 256 panel->appendChild(overflowMenu); |
| 257 |
| 258 MediaControlOverflowMenuListElement* overflowList = MediaControlOverflowMenu
ListElement::create(*this); |
| 259 m_overflowList = overflowList; |
| 260 appendChild(overflowList); |
| 261 |
| 262 m_muteOverflowButton = MediaControlMuteButtonElement::create(*this); |
| 263 m_castOverflowButton = MediaControlCastButtonElement::create(*this, false); |
| 264 m_closedCaptionsOverflowButton = MediaControlToggleClosedCaptionsButtonEleme
nt::create(*this); |
| 265 m_fullscreenOverflowButton = MediaControlFullscreenButtonElement::create(*th
is); |
| 266 |
| 267 m_muteOverflowButton->setShadowPseudoId(AtomicString("-internal-media-contro
ls-overflow-menu-list-item-element")); |
| 268 m_castOverflowButton->setShadowPseudoId(AtomicString("-internal-media-contro
ls-overflow-menu-list-item-element")); |
| 269 m_closedCaptionsOverflowButton->setShadowPseudoId(AtomicString("-internal-me
dia-controls-overflow-menu-list-item-element")); |
| 270 m_fullscreenOverflowButton->setShadowPseudoId(AtomicString("-internal-media-
controls-overflow-menu-list-item-element")); |
| 271 |
| 272 controlsListOverflow = { m_muteOverflowButton, m_closedCaptionsOverflowButto
n, m_castOverflowButton, m_fullscreenOverflowButton }; |
| 245 } | 273 } |
| 246 | 274 |
| 247 void MediaControls::reset() | 275 void MediaControls::reset() |
| 248 { | 276 { |
| 249 EventDispatchForbiddenScope::AllowUserAgentEvents allowEventsInShadow; | 277 EventDispatchForbiddenScope::AllowUserAgentEvents allowEventsInShadow; |
| 250 const bool useNewUi = RuntimeEnabledFeatures::newMediaPlaybackUiEnabled(); | 278 const bool useNewUi = RuntimeEnabledFeatures::newMediaPlaybackUiEnabled(); |
| 251 BatchedControlUpdate batch(this); | 279 BatchedControlUpdate batch(this); |
| 252 | 280 |
| 253 m_allowHiddenVolumeControls = useNewUi; | 281 m_allowHiddenVolumeControls = useNewUi; |
| 254 | 282 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 } | 454 } |
| 427 | 455 |
| 428 // Allow the theme to format the time. | 456 // Allow the theme to format the time. |
| 429 m_currentTimeDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsC
urrentTime(now, duration), IGNORE_EXCEPTION); | 457 m_currentTimeDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsC
urrentTime(now, duration), IGNORE_EXCEPTION); |
| 430 m_currentTimeDisplay->setCurrentValue(now); | 458 m_currentTimeDisplay->setCurrentValue(now); |
| 431 } | 459 } |
| 432 | 460 |
| 433 void MediaControls::updateVolume() | 461 void MediaControls::updateVolume() |
| 434 { | 462 { |
| 435 m_muteButton->updateDisplayType(); | 463 m_muteButton->updateDisplayType(); |
| 464 m_muteOverflowButton->updateDisplayType(); |
| 465 |
| 436 // Invalidate the mute button because it paints differently according to vol
ume. | 466 // Invalidate the mute button because it paints differently according to vol
ume. |
| 437 invalidate(m_muteButton); | 467 invalidate(m_muteButton); |
| 438 | 468 |
| 439 if (mediaElement().muted()) | 469 if (mediaElement().muted()) |
| 440 m_volumeSlider->setVolume(0); | 470 m_volumeSlider->setVolume(0); |
| 441 else | 471 else |
| 442 m_volumeSlider->setVolume(mediaElement().volume()); | 472 m_volumeSlider->setVolume(mediaElement().volume()); |
| 443 | 473 |
| 444 // Update the visibility of our audio elements. | 474 // Update the visibility of our audio elements. |
| 445 // We never want the volume slider if there's no audio. | 475 // We never want the volume slider if there's no audio. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 459 m_muteButton->setIsWanted(mediaElement().hasAudio()); | 489 m_muteButton->setIsWanted(mediaElement().hasAudio()); |
| 460 } | 490 } |
| 461 | 491 |
| 462 // Invalidate the volume slider because it paints differently according to v
olume. | 492 // Invalidate the volume slider because it paints differently according to v
olume. |
| 463 invalidate(m_volumeSlider); | 493 invalidate(m_volumeSlider); |
| 464 } | 494 } |
| 465 | 495 |
| 466 void MediaControls::changedClosedCaptionsVisibility() | 496 void MediaControls::changedClosedCaptionsVisibility() |
| 467 { | 497 { |
| 468 m_toggleClosedCaptionsButton->updateDisplayType(); | 498 m_toggleClosedCaptionsButton->updateDisplayType(); |
| 499 m_closedCaptionsOverflowButton->updateDisplayType(); |
| 469 } | 500 } |
| 470 | 501 |
| 471 void MediaControls::refreshClosedCaptionsButtonVisibility() | 502 void MediaControls::refreshClosedCaptionsButtonVisibility() |
| 472 { | 503 { |
| 473 m_toggleClosedCaptionsButton->setIsWanted(mediaElement().hasClosedCaptions()
); | 504 m_toggleClosedCaptionsButton->setIsWanted(mediaElement().hasClosedCaptions()
); |
| 474 BatchedControlUpdate batch(this); | 505 BatchedControlUpdate batch(this); |
| 475 } | 506 } |
| 476 | 507 |
| 477 void MediaControls::toggleTextTrackList() | 508 void MediaControls::toggleTextTrackList() |
| 478 { | 509 { |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 // This prevents the wrong controls from being shown briefly | 754 // This prevents the wrong controls from being shown briefly |
| 724 // immediately after the first layout and paint, but before we have | 755 // immediately after the first layout and paint, but before we have |
| 725 // a chance to revise them. | 756 // a chance to revise them. |
| 726 for (MediaControlElement* element : elements) { | 757 for (MediaControlElement* element : elements) { |
| 727 if (element) | 758 if (element) |
| 728 element->setDoesFit(false); | 759 element->setDoesFit(false); |
| 729 } | 760 } |
| 730 return; | 761 return; |
| 731 } | 762 } |
| 732 | 763 |
| 764 // Controls that don't fit within the media player that could be included |
| 765 // in an overflow menu. |
| 766 std::set<MediaControlElementType> overflowControls; |
| 767 |
| 733 // For each control that fits, enable it in order of decreasing priority. | 768 // For each control that fits, enable it in order of decreasing priority. |
| 734 bool droppedCastButton = false; | 769 bool droppedCastButton = false; |
| 735 for (MediaControlElement* element : elements) { | 770 for (MediaControlElement* element : elements) { |
| 736 if (!element) | 771 if (!element) |
| 737 continue; | 772 continue; |
| 738 | 773 |
| 739 if (element->isWanted()) { | 774 if (element->isWanted()) { |
| 740 if (usedWidth + minimumWidth <= m_panelWidth) { | 775 if (usedWidth + minimumWidth <= m_panelWidth) { |
| 741 element->setDoesFit(true); | 776 element->setDoesFit(true); |
| 742 usedWidth += minimumWidth; | 777 usedWidth += minimumWidth; |
| 743 } else { | 778 } else { |
| 744 element->setDoesFit(false); | 779 element->setDoesFit(false); |
| 745 if (element == m_castButton.get()) | 780 if (element == m_castButton.get()) |
| 746 droppedCastButton = true; | 781 droppedCastButton = true; |
| 782 overflowControls.insert(element->displayType()); |
| 747 } | 783 } |
| 748 } | 784 } |
| 749 } | 785 } |
| 750 | 786 |
| 787 // We display an overflow menu only when we have at least two items |
| 788 // within it. |
| 789 if (overflowControls.size() >= minOverflowMenuControlElementsNum) { |
| 790 m_overflowList->setOverflowMenuControls(&overflowControls); |
| 791 m_overflowMenu->setIsWanted(true); |
| 792 } else { |
| 793 m_overflowMenu->setIsWanted(false); |
| 794 m_overflowList->showOverflowMenu(false); |
| 795 } |
| 796 |
| 751 // Special case for cast: if we want a cast button but dropped it, then | 797 // Special case for cast: if we want a cast button but dropped it, then |
| 752 // show the overlay cast button instead. | 798 // show the overlay cast button instead. |
| 753 if (m_castButton->isWanted()) { | 799 if (m_castButton->isWanted()) { |
| 754 if (droppedCastButton) | 800 if (droppedCastButton) |
| 755 m_overlayCastButton->tryShowOverlay(); | 801 m_overlayCastButton->tryShowOverlay(); |
| 756 else | 802 else |
| 757 m_overlayCastButton->setIsWanted(false); | 803 m_overlayCastButton->setIsWanted(false); |
| 758 } | 804 } |
| 759 } | 805 } |
| 760 | 806 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 777 void MediaControls::networkStateChanged() | 823 void MediaControls::networkStateChanged() |
| 778 { | 824 { |
| 779 invalidate(m_playButton); | 825 invalidate(m_playButton); |
| 780 invalidate(m_overlayPlayButton); | 826 invalidate(m_overlayPlayButton); |
| 781 invalidate(m_muteButton); | 827 invalidate(m_muteButton); |
| 782 invalidate(m_fullScreenButton); | 828 invalidate(m_fullScreenButton); |
| 783 invalidate(m_timeline); | 829 invalidate(m_timeline); |
| 784 invalidate(m_volumeSlider); | 830 invalidate(m_volumeSlider); |
| 785 } | 831 } |
| 786 | 832 |
| 833 bool MediaControls::overflowMenuVisible() |
| 834 { |
| 835 return m_overflowList->isWanted(); |
| 836 } |
| 837 |
| 838 void MediaControls::toggleOverflowMenu() |
| 839 { |
| 840 m_overflowList->showOverflowMenu(!m_overflowList->isWanted()); |
| 841 } |
| 842 |
| 843 std::vector<MediaControlInputElement*> MediaControls::getOverflowMenuButtons() |
| 844 { |
| 845 return controlsListOverflow; |
| 846 } |
| 847 |
| 787 DEFINE_TRACE(MediaControls) | 848 DEFINE_TRACE(MediaControls) |
| 788 { | 849 { |
| 789 visitor->trace(m_mediaElement); | 850 visitor->trace(m_mediaElement); |
| 790 visitor->trace(m_panel); | 851 visitor->trace(m_panel); |
| 791 visitor->trace(m_overlayPlayButton); | 852 visitor->trace(m_overlayPlayButton); |
| 792 visitor->trace(m_overlayEnclosure); | 853 visitor->trace(m_overlayEnclosure); |
| 793 visitor->trace(m_playButton); | 854 visitor->trace(m_playButton); |
| 794 visitor->trace(m_currentTimeDisplay); | 855 visitor->trace(m_currentTimeDisplay); |
| 795 visitor->trace(m_timeline); | 856 visitor->trace(m_timeline); |
| 796 visitor->trace(m_muteButton); | 857 visitor->trace(m_muteButton); |
| 797 visitor->trace(m_volumeSlider); | 858 visitor->trace(m_volumeSlider); |
| 798 visitor->trace(m_toggleClosedCaptionsButton); | 859 visitor->trace(m_toggleClosedCaptionsButton); |
| 799 visitor->trace(m_fullScreenButton); | 860 visitor->trace(m_fullScreenButton); |
| 800 visitor->trace(m_durationDisplay); | 861 visitor->trace(m_durationDisplay); |
| 801 visitor->trace(m_enclosure); | 862 visitor->trace(m_enclosure); |
| 802 visitor->trace(m_textTrackList); | 863 visitor->trace(m_textTrackList); |
| 864 visitor->trace(m_overflowMenu); |
| 865 visitor->trace(m_overflowList); |
| 866 visitor->trace(m_muteOverflowButton); |
| 867 visitor->trace(m_castOverflowButton); |
| 868 visitor->trace(m_closedCaptionsOverflowButton); |
| 869 visitor->trace(m_fullscreenOverflowButton); |
| 803 visitor->trace(m_castButton); | 870 visitor->trace(m_castButton); |
| 804 visitor->trace(m_overlayCastButton); | 871 visitor->trace(m_overlayCastButton); |
| 805 HTMLDivElement::trace(visitor); | 872 HTMLDivElement::trace(visitor); |
| 806 } | 873 } |
| 807 | 874 |
| 808 } // namespace blink | 875 } // namespace blink |
| OLD | NEW |