Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(566)

Side by Side Diff: third_party/WebKit/Source/core/html/shadow/MediaControls.cpp

Issue 2701433003: Hide overlay play button if it can't be shown without clipping (Closed)
Patch Set: Refactor to use ResizeObserver Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 11 matching lines...) Expand all
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27 #include "core/html/shadow/MediaControls.h" 27 #include "core/html/shadow/MediaControls.h"
28 28
29 #include "bindings/core/v8/ExceptionState.h" 29 #include "bindings/core/v8/ExceptionState.h"
30 #include "core/dom/ClientRect.h" 30 #include "core/dom/ClientRect.h"
31 #include "core/dom/Fullscreen.h" 31 #include "core/dom/Fullscreen.h"
32 #include "core/dom/ResizeObserver.h"
33 #include "core/dom/ResizeObserverCallback.h"
34 #include "core/dom/ResizeObserverEntry.h"
32 #include "core/dom/TaskRunnerHelper.h" 35 #include "core/dom/TaskRunnerHelper.h"
33 #include "core/events/MouseEvent.h" 36 #include "core/events/MouseEvent.h"
34 #include "core/frame/Settings.h" 37 #include "core/frame/Settings.h"
35 #include "core/html/HTMLMediaElement.h" 38 #include "core/html/HTMLMediaElement.h"
36 #include "core/html/HTMLVideoElement.h" 39 #include "core/html/HTMLVideoElement.h"
37 #include "core/html/shadow/MediaControlsMediaEventListener.h" 40 #include "core/html/shadow/MediaControlsMediaEventListener.h"
38 #include "core/html/shadow/MediaControlsOrientationLockDelegate.h" 41 #include "core/html/shadow/MediaControlsOrientationLockDelegate.h"
39 #include "core/html/shadow/MediaControlsWindowEventListener.h" 42 #include "core/html/shadow/MediaControlsWindowEventListener.h"
40 #include "core/html/track/TextTrackContainer.h" 43 #include "core/html/track/TextTrackContainer.h"
41 #include "core/html/track/TextTrackList.h" 44 #include "core/html/track/TextTrackList.h"
42 #include "core/layout/LayoutObject.h" 45 #include "core/layout/LayoutObject.h"
43 #include "core/layout/LayoutTheme.h" 46 #include "core/layout/LayoutTheme.h"
44 #include "platform/EventDispatchForbiddenScope.h" 47 #include "platform/EventDispatchForbiddenScope.h"
45 48
46 namespace blink { 49 namespace blink {
47 50
51 namespace {
52 constexpr int kOverlayPlayButtonWidth = 48;
53 constexpr int kOverlayPlayButtonHeight = 48;
54 constexpr int kOverlayBottomMargin = 10;
55 constexpr int kAndroidMediaPanelHeight = 48;
56
57 constexpr int kMinWidthForOverlayPlayButton = kOverlayPlayButtonWidth;
58 constexpr int kMinHeightForOverlayPlayButton = kOverlayPlayButtonHeight +
59 (2 * kAndroidMediaPanelHeight) +
60 (2 * kOverlayBottomMargin);
61 } // namespace
62
48 // If you change this value, then also update the corresponding value in 63 // If you change this value, then also update the corresponding value in
49 // LayoutTests/media/media-controls.js. 64 // LayoutTests/media/media-controls.js.
50 static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3; 65 static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3;
51 66
52 static bool shouldShowFullscreenButton(const HTMLMediaElement& mediaElement) { 67 static bool shouldShowFullscreenButton(const HTMLMediaElement& mediaElement) {
53 // Unconditionally allow the user to exit fullscreen if we are in it 68 // Unconditionally allow the user to exit fullscreen if we are in it
54 // now. Especially on android, when we might not yet know if 69 // now. Especially on android, when we might not yet know if
55 // fullscreen is supported, we sometimes guess incorrectly and show 70 // fullscreen is supported, we sometimes guess incorrectly and show
56 // the button earlier, and we don't want to remove it here if the 71 // the button earlier, and we don't want to remove it here if the
57 // user chose to enter fullscreen. crbug.com/500732 . 72 // user chose to enter fullscreen. crbug.com/500732 .
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 } 114 }
100 115
101 private: 116 private:
102 Member<MediaControls> m_controls; 117 Member<MediaControls> m_controls;
103 static int s_batchDepth; 118 static int s_batchDepth;
104 }; 119 };
105 120
106 // Count of number open batches for controls visibility. 121 // Count of number open batches for controls visibility.
107 int MediaControls::BatchedControlUpdate::s_batchDepth = 0; 122 int MediaControls::BatchedControlUpdate::s_batchDepth = 0;
108 123
124 class MediaControls::MediaControlsResizeObserverCallback
125 : public ResizeObserverCallback {
126 public:
127 explicit MediaControlsResizeObserverCallback(MediaControls* controls)
128 : m_controls(controls) {
129 DCHECK(controls);
130 }
131 ~MediaControlsResizeObserverCallback() override{};
mlamouri (slow - plz ping) 2017/02/22 11:48:08 nit: s/{};/ = default;/
steimel 2017/02/23 00:53:48 Done.
132
133 void handleEvent(const HeapVector<Member<ResizeObserverEntry>>& entries,
134 ResizeObserver* observer) override {
135 for (const auto& entry : entries) {
mlamouri (slow - plz ping) 2017/02/22 11:48:08 Is more than one entry expected? Should we DCHECK(
steimel 2017/02/23 00:53:48 Discussed offline. After looking at the spec, ther
136 m_controls->notifyPanelSizeChanged((int)entry->contentRect()->width(),
137 (int)entry->contentRect()->height());
138 }
139 }
140
141 DEFINE_INLINE_TRACE() {
142 visitor->trace(m_controls);
143 ResizeObserverCallback::trace(visitor);
144 }
145
146 private:
147 Member<MediaControls> m_controls;
148 };
149
109 MediaControls::MediaControls(HTMLMediaElement& mediaElement) 150 MediaControls::MediaControls(HTMLMediaElement& mediaElement)
110 : HTMLDivElement(mediaElement.document()), 151 : HTMLDivElement(mediaElement.document()),
152 m_resizeObserver(ResizeObserver::create(
153 mediaElement.document(),
154 new MediaControlsResizeObserverCallback(this))),
111 m_mediaElement(&mediaElement), 155 m_mediaElement(&mediaElement),
112 m_overlayEnclosure(nullptr), 156 m_overlayEnclosure(nullptr),
113 m_overlayPlayButton(nullptr), 157 m_overlayPlayButton(nullptr),
114 m_overlayCastButton(nullptr), 158 m_overlayCastButton(nullptr),
115 m_enclosure(nullptr), 159 m_enclosure(nullptr),
116 m_panel(nullptr), 160 m_panel(nullptr),
117 m_playButton(nullptr), 161 m_playButton(nullptr),
118 m_timeline(nullptr), 162 m_timeline(nullptr),
119 m_currentTimeDisplay(nullptr), 163 m_currentTimeDisplay(nullptr),
120 m_durationDisplay(nullptr), 164 m_durationDisplay(nullptr),
(...skipping 10 matching lines...) Expand all
131 this, 175 this,
132 WTF::bind(&MediaControls::hideAllMenus, wrapWeakPersistent(this)))), 176 WTF::bind(&MediaControls::hideAllMenus, wrapWeakPersistent(this)))),
133 m_orientationLockDelegate(nullptr), 177 m_orientationLockDelegate(nullptr),
134 m_hideMediaControlsTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer, 178 m_hideMediaControlsTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer,
135 &mediaElement.document()), 179 &mediaElement.document()),
136 this, 180 this,
137 &MediaControls::hideMediaControlsTimerFired), 181 &MediaControls::hideMediaControlsTimerFired),
138 m_hideTimerBehaviorFlags(IgnoreNone), 182 m_hideTimerBehaviorFlags(IgnoreNone),
139 m_isMouseOverControls(false), 183 m_isMouseOverControls(false),
140 m_isPausedForScrubbing(false), 184 m_isPausedForScrubbing(false),
141 m_panelWidthChangedTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer, 185 m_panelSizeChangedTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer,
142 &mediaElement.document()), 186 &mediaElement.document()),
143 this, 187 this,
144 &MediaControls::panelWidthChangedTimerFired), 188 &MediaControls::panelSizeChangedTimerFired),
145 m_panelWidth(0), 189 m_panelWidth(0),
146 m_keepShowingUntilTimerFires(false) {} 190 m_panelHeight(0),
191 m_keepShowingUntilTimerFires(false) {
192 m_resizeObserver->observe(m_mediaElement);
mlamouri (slow - plz ping) 2017/02/22 11:48:08 Would it make sense to initialise the current size
steimel 2017/02/23 00:53:48 Discussed offline, but re-adding some code in Layo
193 }
147 194
148 MediaControls* MediaControls::create(HTMLMediaElement& mediaElement, 195 MediaControls* MediaControls::create(HTMLMediaElement& mediaElement,
149 ShadowRoot& shadowRoot) { 196 ShadowRoot& shadowRoot) {
150 MediaControls* controls = new MediaControls(mediaElement); 197 MediaControls* controls = new MediaControls(mediaElement);
151 controls->setShadowPseudoId(AtomicString("-webkit-media-controls")); 198 controls->setShadowPseudoId(AtomicString("-webkit-media-controls"));
152 controls->initializeControls(); 199 controls->initializeControls();
153 controls->reset(); 200 controls->reset();
154 201
155 // Initialize the orientation lock when going fullscreen feature. 202 // Initialize the orientation lock when going fullscreen feature.
156 if (RuntimeEnabledFeatures::videoFullscreenOrientationLockEnabled() && 203 if (RuntimeEnabledFeatures::videoFullscreenOrientationLockEnabled() &&
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 stopHideMediaControlsTimer(); 821 stopHideMediaControlsTimer();
775 startHideMediaControlsTimer(); 822 startHideMediaControlsTimer();
776 } 823 }
777 824
778 void MediaControls::onExitedFullscreen() { 825 void MediaControls::onExitedFullscreen() {
779 m_fullscreenButton->setIsFullscreen(false); 826 m_fullscreenButton->setIsFullscreen(false);
780 stopHideMediaControlsTimer(); 827 stopHideMediaControlsTimer();
781 startHideMediaControlsTimer(); 828 startHideMediaControlsTimer();
782 } 829 }
783 830
784 void MediaControls::notifyPanelWidthChanged(const LayoutUnit& newWidth) { 831 void MediaControls::notifyPanelSizeChanged(int newWidth, int newHeight) {
785 // Don't bother to do any work if this matches the most recent panel 832 // Don't bother to do any work if this matches the most recent panel
786 // width, since we're called after layout. 833 // size, since we're called after layout.
787 // Note that this code permits a bad frame on resize, since it is 834 // Note that this code permits a bad frame on resize, since it is
788 // run after the relayout / paint happens. It would be great to improve 835 // run after the relayout / paint happens. It would be great to improve
789 // this, but it would be even greater to move this code entirely to 836 // this, but it would be even greater to move this code entirely to
790 // JS and fix it there. 837 // JS and fix it there.
791 m_panelWidth = newWidth.toInt(); 838 m_panelWidth = newWidth;
839 m_panelHeight = newHeight;
mlamouri (slow - plz ping) 2017/02/22 11:48:08 Is it really still the panel width/height? Shouldn
steimel 2017/02/23 00:53:48 Done.
792 840
793 // Adjust for effective zoom. 841 // Adjust for effective zoom.
794 if (!m_panel->layoutObject() || !m_panel->layoutObject()->style()) 842 if (!m_panel->layoutObject() || !m_panel->layoutObject()->style())
795 return; 843 return;
844
796 m_panelWidth = 845 m_panelWidth =
797 ceil(m_panelWidth / m_panel->layoutObject()->style()->effectiveZoom()); 846 ceil(m_panelWidth / m_panel->layoutObject()->style()->effectiveZoom());
798 847
799 m_panelWidthChangedTimer.startOneShot(0, BLINK_FROM_HERE); 848 m_panelSizeChangedTimer.startOneShot(0, BLINK_FROM_HERE);
800 } 849 }
801 850
802 void MediaControls::panelWidthChangedTimerFired(TimerBase*) { 851 void MediaControls::panelSizeChangedTimerFired(TimerBase*) {
803 computeWhichControlsFit(); 852 computeWhichControlsFit();
804 } 853 }
805 854
806 void MediaControls::computeWhichControlsFit() { 855 void MediaControls::computeWhichControlsFit() {
807 // Hide all controls that don't fit, and show the ones that do. 856 // Hide all controls that don't fit, and show the ones that do.
808 // This might be better suited for a layout, but since JS media controls 857 // This might be better suited for a layout, but since JS media controls
809 // won't benefit from that anwyay, we just do it here like JS will. 858 // won't benefit from that anwyay, we just do it here like JS will.
810 859
811 // Controls that we'll hide / show, in order of decreasing priority. 860 // Controls that we'll hide / show, in order of decreasing priority.
812 MediaControlElement* elements[] = { 861 MediaControlElement* elements[] = {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 if ((firstDisplacedElement == m_timeline.get()) || 952 if ((firstDisplacedElement == m_timeline.get()) ||
904 (firstDisplacedElement == m_volumeSlider.get())) 953 (firstDisplacedElement == m_volumeSlider.get()))
905 width += sliderMargin; 954 width += sliderMargin;
906 if (usedWidth + width <= m_panelWidth) 955 if (usedWidth + width <= m_panelWidth)
907 firstDisplacedElement->setDoesFit(true); 956 firstDisplacedElement->setDoesFit(true);
908 } 957 }
909 } else if (overflowElements.size() == 1) { 958 } else if (overflowElements.size() == 1) {
910 m_overflowMenu->setIsWanted(false); 959 m_overflowMenu->setIsWanted(false);
911 overflowElements.front()->setDoesFit(true); 960 overflowElements.front()->setDoesFit(true);
912 } 961 }
962
963 // Decide if the overlay play button fits.
964 if (m_panelWidth && m_panelHeight && m_overlayPlayButton) {
965 bool doesFit = m_panelWidth >= kMinWidthForOverlayPlayButton &&
966 m_panelHeight >= kMinHeightForOverlayPlayButton;
967 m_overlayPlayButton->setDoesFit(doesFit);
968 }
913 } 969 }
914 970
915 void MediaControls::invalidate(Element* element) { 971 void MediaControls::invalidate(Element* element) {
916 if (!element) 972 if (!element)
917 return; 973 return;
918 974
919 if (LayoutObject* layoutObject = element->layoutObject()) 975 if (LayoutObject* layoutObject = element->layoutObject())
920 layoutObject 976 layoutObject
921 ->setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants(); 977 ->setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
922 } 978 }
(...skipping 23 matching lines...) Expand all
946 void MediaControls::hideAllMenus() { 1002 void MediaControls::hideAllMenus() {
947 m_windowEventListener->stop(); 1003 m_windowEventListener->stop();
948 1004
949 if (m_overflowList->isWanted()) 1005 if (m_overflowList->isWanted())
950 m_overflowList->setIsWanted(false); 1006 m_overflowList->setIsWanted(false);
951 if (m_textTrackList->isWanted()) 1007 if (m_textTrackList->isWanted())
952 m_textTrackList->setVisible(false); 1008 m_textTrackList->setVisible(false);
953 } 1009 }
954 1010
955 DEFINE_TRACE(MediaControls) { 1011 DEFINE_TRACE(MediaControls) {
1012 visitor->trace(m_resizeObserver);
956 visitor->trace(m_mediaElement); 1013 visitor->trace(m_mediaElement);
957 visitor->trace(m_panel); 1014 visitor->trace(m_panel);
958 visitor->trace(m_overlayPlayButton); 1015 visitor->trace(m_overlayPlayButton);
959 visitor->trace(m_overlayEnclosure); 1016 visitor->trace(m_overlayEnclosure);
960 visitor->trace(m_playButton); 1017 visitor->trace(m_playButton);
961 visitor->trace(m_currentTimeDisplay); 1018 visitor->trace(m_currentTimeDisplay);
962 visitor->trace(m_timeline); 1019 visitor->trace(m_timeline);
963 visitor->trace(m_muteButton); 1020 visitor->trace(m_muteButton);
964 visitor->trace(m_volumeSlider); 1021 visitor->trace(m_volumeSlider);
965 visitor->trace(m_toggleClosedCaptionsButton); 1022 visitor->trace(m_toggleClosedCaptionsButton);
966 visitor->trace(m_fullscreenButton); 1023 visitor->trace(m_fullscreenButton);
967 visitor->trace(m_downloadButton); 1024 visitor->trace(m_downloadButton);
968 visitor->trace(m_durationDisplay); 1025 visitor->trace(m_durationDisplay);
969 visitor->trace(m_enclosure); 1026 visitor->trace(m_enclosure);
970 visitor->trace(m_textTrackList); 1027 visitor->trace(m_textTrackList);
971 visitor->trace(m_overflowMenu); 1028 visitor->trace(m_overflowMenu);
972 visitor->trace(m_overflowList); 1029 visitor->trace(m_overflowList);
973 visitor->trace(m_castButton); 1030 visitor->trace(m_castButton);
974 visitor->trace(m_overlayCastButton); 1031 visitor->trace(m_overlayCastButton);
975 visitor->trace(m_mediaEventListener); 1032 visitor->trace(m_mediaEventListener);
976 visitor->trace(m_windowEventListener); 1033 visitor->trace(m_windowEventListener);
977 visitor->trace(m_orientationLockDelegate); 1034 visitor->trace(m_orientationLockDelegate);
978 HTMLDivElement::trace(visitor); 1035 HTMLDivElement::trace(visitor);
979 } 1036 }
980 1037
981 } // namespace blink 1038 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698