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 |
11 * notice, this list of conditions and the following disclaimer in the | 11 * notice, this list of conditions and the following disclaimer in the |
12 * documentation and/or other materials provided with the distribution. | 12 * documentation and/or other materials provided with the distribution. |
13 * | 13 * |
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
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 "modules/media_controls/MediaControlsImpl.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" | 32 #include "core/dom/ResizeObserver.h" |
33 #include "core/dom/ResizeObserverCallback.h" | 33 #include "core/dom/ResizeObserverCallback.h" |
34 #include "core/dom/ResizeObserverEntry.h" | 34 #include "core/dom/ResizeObserverEntry.h" |
35 #include "core/dom/TaskRunnerHelper.h" | 35 #include "core/dom/TaskRunnerHelper.h" |
36 #include "core/events/MouseEvent.h" | 36 #include "core/events/MouseEvent.h" |
37 #include "core/frame/Settings.h" | 37 #include "core/frame/Settings.h" |
38 #include "core/frame/UseCounter.h" | 38 #include "core/frame/UseCounter.h" |
39 #include "core/html/HTMLMediaElement.h" | 39 #include "core/html/HTMLMediaElement.h" |
40 #include "core/html/HTMLVideoElement.h" | 40 #include "core/html/HTMLVideoElement.h" |
41 #include "core/html/media/HTMLMediaElementControlsList.h" | 41 #include "core/html/media/HTMLMediaElementControlsList.h" |
42 #include "core/html/shadow/MediaControlsMediaEventListener.h" | 42 #include "core/html/shadow/MediaControlsMediaEventListener.h" |
43 #include "core/html/shadow/MediaControlsOrientationLockDelegate.h" | |
44 #include "core/html/shadow/MediaControlsWindowEventListener.h" | 43 #include "core/html/shadow/MediaControlsWindowEventListener.h" |
45 #include "core/html/track/TextTrackContainer.h" | 44 #include "core/html/track/TextTrackContainer.h" |
46 #include "core/html/track/TextTrackList.h" | 45 #include "core/html/track/TextTrackList.h" |
47 #include "core/layout/LayoutObject.h" | 46 #include "core/layout/LayoutObject.h" |
48 #include "core/layout/LayoutTheme.h" | 47 #include "core/layout/LayoutTheme.h" |
| 48 #include "modules/media_controls/MediaControlsOrientationLockDelegate.h" |
49 #include "platform/EventDispatchForbiddenScope.h" | 49 #include "platform/EventDispatchForbiddenScope.h" |
50 | 50 |
51 namespace blink { | 51 namespace blink { |
52 | 52 |
53 namespace { | 53 namespace { |
54 | 54 |
55 // TODO(steimel): should have better solution than hard-coding pixel values. | 55 // TODO(steimel): should have better solution than hard-coding pixel values. |
56 // Defined in core/css/mediaControls.css, core/css/mediaControlsAndroid.css, | 56 // Defined in core/css/mediaControls.css, core/css/mediaControlsAndroid.css, |
57 // and core/paint/MediaControlsPainter.cpp. | 57 // and core/paint/MediaControlsPainter.cpp. |
58 constexpr int kOverlayPlayButtonWidth = 48; | 58 constexpr int kOverlayPlayButtonWidth = 48; |
59 constexpr int kOverlayPlayButtonHeight = 48; | 59 constexpr int kOverlayPlayButtonHeight = 48; |
60 constexpr int kOverlayBottomMargin = 10; | 60 constexpr int kOverlayBottomMargin = 10; |
61 constexpr int kAndroidMediaPanelHeight = 48; | 61 constexpr int kAndroidMediaPanelHeight = 48; |
62 | 62 |
63 constexpr int kMinWidthForOverlayPlayButton = kOverlayPlayButtonWidth; | 63 constexpr int kMinWidthForOverlayPlayButton = kOverlayPlayButtonWidth; |
64 constexpr int kMinHeightForOverlayPlayButton = kOverlayPlayButtonHeight + | 64 constexpr int kMinHeightForOverlayPlayButton = kOverlayPlayButtonHeight + |
65 kAndroidMediaPanelHeight + | 65 kAndroidMediaPanelHeight + |
66 (2 * kOverlayBottomMargin); | 66 (2 * kOverlayBottomMargin); |
67 | 67 |
68 } // anonymous namespace | |
69 | |
70 // If you change this value, then also update the corresponding value in | 68 // If you change this value, then also update the corresponding value in |
71 // LayoutTests/media/media-controls.js. | 69 // LayoutTests/media/media-controls.js. |
72 static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3; | 70 const double timeWithoutMouseMovementBeforeHidingMediaControls = 3; |
73 | 71 |
74 static bool shouldShowFullscreenButton(const HTMLMediaElement& mediaElement) { | 72 bool shouldShowFullscreenButton(const HTMLMediaElement& mediaElement) { |
75 // Unconditionally allow the user to exit fullscreen if we are in it | 73 // Unconditionally allow the user to exit fullscreen if we are in it |
76 // now. Especially on android, when we might not yet know if | 74 // now. Especially on android, when we might not yet know if |
77 // fullscreen is supported, we sometimes guess incorrectly and show | 75 // fullscreen is supported, we sometimes guess incorrectly and show |
78 // the button earlier, and we don't want to remove it here if the | 76 // the button earlier, and we don't want to remove it here if the |
79 // user chose to enter fullscreen. crbug.com/500732 . | 77 // user chose to enter fullscreen. crbug.com/500732 . |
80 if (mediaElement.isFullscreen()) | 78 if (mediaElement.isFullscreen()) |
81 return true; | 79 return true; |
82 | 80 |
83 if (!mediaElement.isHTMLVideoElement()) | 81 if (!mediaElement.isHTMLVideoElement()) |
84 return false; | 82 return false; |
85 | 83 |
86 if (!mediaElement.hasVideo()) | 84 if (!mediaElement.hasVideo()) |
87 return false; | 85 return false; |
88 | 86 |
89 if (!Fullscreen::fullscreenEnabled(mediaElement.document())) | 87 if (!Fullscreen::fullscreenEnabled(mediaElement.document())) |
90 return false; | 88 return false; |
91 | 89 |
92 if (mediaElement.controlsListInternal()->shouldHideFullscreen()) { | 90 if (mediaElement.controlsListInternal()->shouldHideFullscreen()) { |
93 UseCounter::count(mediaElement.document(), | 91 UseCounter::count(mediaElement.document(), |
94 UseCounter::HTMLMediaElementControlsListNoFullscreen); | 92 UseCounter::HTMLMediaElementControlsListNoFullscreen); |
95 return false; | 93 return false; |
96 } | 94 } |
97 | 95 |
98 return true; | 96 return true; |
99 } | 97 } |
100 | 98 |
101 static bool shouldShowCastButton(HTMLMediaElement& mediaElement) { | 99 bool shouldShowCastButton(HTMLMediaElement& mediaElement) { |
102 if (mediaElement.fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) | 100 if (mediaElement.fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) |
103 return false; | 101 return false; |
104 | 102 |
105 // Explicitly do not show cast button when the mediaControlsEnabled setting is | 103 // Explicitly do not show cast button when the mediaControlsEnabled setting is |
106 // false to make sure the overlay does not appear. | 104 // false to make sure the overlay does not appear. |
107 Document& document = mediaElement.document(); | 105 Document& document = mediaElement.document(); |
108 if (document.settings() && !document.settings()->getMediaControlsEnabled()) | 106 if (document.settings() && !document.settings()->getMediaControlsEnabled()) |
109 return false; | 107 return false; |
110 | 108 |
111 // The page disabled the button via the attribute. | 109 // The page disabled the button via the attribute. |
112 if (mediaElement.controlsListInternal()->shouldHideRemotePlayback()) { | 110 if (mediaElement.controlsListInternal()->shouldHideRemotePlayback()) { |
113 UseCounter::count(mediaElement.document(), | 111 UseCounter::count(mediaElement.document(), |
114 UseCounter::HTMLMediaElementControlsListNoRemotePlayback); | 112 UseCounter::HTMLMediaElementControlsListNoRemotePlayback); |
115 return false; | 113 return false; |
116 } | 114 } |
117 | 115 |
118 return mediaElement.hasRemoteRoutes(); | 116 return mediaElement.hasRemoteRoutes(); |
119 } | 117 } |
120 | 118 |
121 static bool preferHiddenVolumeControls(const Document& document) { | 119 bool preferHiddenVolumeControls(const Document& document) { |
122 return !document.settings() || | 120 return !document.settings() || |
123 document.settings()->getPreferHiddenVolumeControls(); | 121 document.settings()->getPreferHiddenVolumeControls(); |
124 } | 122 } |
125 | 123 |
126 class MediaControls::BatchedControlUpdate { | 124 } // anonymous namespace |
| 125 |
| 126 class MediaControlsImpl::BatchedControlUpdate { |
127 WTF_MAKE_NONCOPYABLE(BatchedControlUpdate); | 127 WTF_MAKE_NONCOPYABLE(BatchedControlUpdate); |
128 STACK_ALLOCATED(); | 128 STACK_ALLOCATED(); |
129 | 129 |
130 public: | 130 public: |
131 explicit BatchedControlUpdate(MediaControls* controls) | 131 explicit BatchedControlUpdate(MediaControlsImpl* controls) |
132 : m_controls(controls) { | 132 : m_controls(controls) { |
133 DCHECK(isMainThread()); | 133 DCHECK(isMainThread()); |
134 DCHECK_GE(s_batchDepth, 0); | 134 DCHECK_GE(s_batchDepth, 0); |
135 ++s_batchDepth; | 135 ++s_batchDepth; |
136 } | 136 } |
137 ~BatchedControlUpdate() { | 137 ~BatchedControlUpdate() { |
138 DCHECK(isMainThread()); | 138 DCHECK(isMainThread()); |
139 DCHECK_GT(s_batchDepth, 0); | 139 DCHECK_GT(s_batchDepth, 0); |
140 if (!(--s_batchDepth)) | 140 if (!(--s_batchDepth)) |
141 m_controls->computeWhichControlsFit(); | 141 m_controls->computeWhichControlsFit(); |
142 } | 142 } |
143 | 143 |
144 private: | 144 private: |
145 Member<MediaControls> m_controls; | 145 Member<MediaControlsImpl> m_controls; |
146 static int s_batchDepth; | 146 static int s_batchDepth; |
147 }; | 147 }; |
148 | 148 |
149 // Count of number open batches for controls visibility. | 149 // Count of number open batches for controls visibility. |
150 int MediaControls::BatchedControlUpdate::s_batchDepth = 0; | 150 int MediaControlsImpl::BatchedControlUpdate::s_batchDepth = 0; |
151 | 151 |
152 class MediaControls::MediaControlsResizeObserverCallback final | 152 class MediaControlsImpl::MediaControlsResizeObserverCallback final |
153 : public ResizeObserverCallback { | 153 : public ResizeObserverCallback { |
154 public: | 154 public: |
155 explicit MediaControlsResizeObserverCallback(MediaControls* controls) | 155 explicit MediaControlsResizeObserverCallback(MediaControlsImpl* controls) |
156 : m_controls(controls) { | 156 : m_controls(controls) { |
157 DCHECK(controls); | 157 DCHECK(controls); |
158 } | 158 } |
159 ~MediaControlsResizeObserverCallback() override = default; | 159 ~MediaControlsResizeObserverCallback() override = default; |
160 | 160 |
161 void handleEvent(const HeapVector<Member<ResizeObserverEntry>>& entries, | 161 void handleEvent(const HeapVector<Member<ResizeObserverEntry>>& entries, |
162 ResizeObserver* observer) override { | 162 ResizeObserver* observer) override { |
163 DCHECK_EQ(1u, entries.size()); | 163 DCHECK_EQ(1u, entries.size()); |
164 DCHECK_EQ(entries[0]->target(), m_controls->m_mediaElement); | 164 DCHECK_EQ(entries[0]->target(), m_controls->mediaElement()); |
165 m_controls->notifyElementSizeChanged(entries[0]->contentRect()); | 165 m_controls->notifyElementSizeChanged(entries[0]->contentRect()); |
166 } | 166 } |
167 | 167 |
168 DEFINE_INLINE_TRACE() { | 168 DEFINE_INLINE_TRACE() { |
169 visitor->trace(m_controls); | 169 visitor->trace(m_controls); |
170 ResizeObserverCallback::trace(visitor); | 170 ResizeObserverCallback::trace(visitor); |
171 } | 171 } |
172 | 172 |
173 private: | 173 private: |
174 Member<MediaControls> m_controls; | 174 Member<MediaControlsImpl> m_controls; |
175 }; | 175 }; |
176 | 176 |
177 MediaControls::MediaControls(HTMLMediaElement& mediaElement) | 177 MediaControls* MediaControlsImpl::Factory::create( |
| 178 HTMLMediaElement& mediaElement, |
| 179 ShadowRoot& shadowRoot) { |
| 180 return MediaControlsImpl::create(mediaElement, shadowRoot); |
| 181 } |
| 182 |
| 183 MediaControlsImpl::MediaControlsImpl(HTMLMediaElement& mediaElement) |
178 : HTMLDivElement(mediaElement.document()), | 184 : HTMLDivElement(mediaElement.document()), |
179 m_mediaElement(&mediaElement), | 185 MediaControls(mediaElement), |
180 m_overlayEnclosure(nullptr), | 186 m_overlayEnclosure(nullptr), |
181 m_overlayPlayButton(nullptr), | 187 m_overlayPlayButton(nullptr), |
182 m_overlayCastButton(nullptr), | 188 m_overlayCastButton(nullptr), |
183 m_enclosure(nullptr), | 189 m_enclosure(nullptr), |
184 m_panel(nullptr), | 190 m_panel(nullptr), |
185 m_playButton(nullptr), | 191 m_playButton(nullptr), |
186 m_timeline(nullptr), | 192 m_timeline(nullptr), |
187 m_currentTimeDisplay(nullptr), | 193 m_currentTimeDisplay(nullptr), |
188 m_durationDisplay(nullptr), | 194 m_durationDisplay(nullptr), |
189 m_muteButton(nullptr), | 195 m_muteButton(nullptr), |
190 m_volumeSlider(nullptr), | 196 m_volumeSlider(nullptr), |
191 m_toggleClosedCaptionsButton(nullptr), | 197 m_toggleClosedCaptionsButton(nullptr), |
192 m_textTrackList(nullptr), | 198 m_textTrackList(nullptr), |
193 m_overflowList(nullptr), | 199 m_overflowList(nullptr), |
194 m_castButton(nullptr), | 200 m_castButton(nullptr), |
195 m_fullscreenButton(nullptr), | 201 m_fullscreenButton(nullptr), |
196 m_downloadButton(nullptr), | 202 m_downloadButton(nullptr), |
197 m_mediaEventListener(new MediaControlsMediaEventListener(this)), | 203 m_mediaEventListener(new MediaControlsMediaEventListener(this)), |
198 m_windowEventListener(MediaControlsWindowEventListener::create( | 204 m_windowEventListener(MediaControlsWindowEventListener::create( |
199 this, | 205 this, |
200 WTF::bind(&MediaControls::hideAllMenus, wrapWeakPersistent(this)))), | 206 WTF::bind(&MediaControlsImpl::hideAllMenus, |
| 207 wrapWeakPersistent(this)))), |
201 m_orientationLockDelegate(nullptr), | 208 m_orientationLockDelegate(nullptr), |
202 m_hideMediaControlsTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer, | 209 m_hideMediaControlsTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer, |
203 &mediaElement.document()), | 210 &mediaElement.document()), |
204 this, | 211 this, |
205 &MediaControls::hideMediaControlsTimerFired), | 212 &MediaControlsImpl::hideMediaControlsTimerFired), |
206 m_hideTimerBehaviorFlags(IgnoreNone), | 213 m_hideTimerBehaviorFlags(IgnoreNone), |
207 m_isMouseOverControls(false), | 214 m_isMouseOverControls(false), |
208 m_isPausedForScrubbing(false), | 215 m_isPausedForScrubbing(false), |
209 m_resizeObserver(ResizeObserver::create( | 216 m_resizeObserver(ResizeObserver::create( |
210 mediaElement.document(), | 217 mediaElement.document(), |
211 new MediaControlsResizeObserverCallback(this))), | 218 new MediaControlsResizeObserverCallback(this))), |
212 m_elementSizeChangedTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer, | 219 m_elementSizeChangedTimer( |
213 &mediaElement.document()), | 220 TaskRunnerHelper::get(TaskType::UnspecedTimer, |
214 this, | 221 &mediaElement.document()), |
215 &MediaControls::elementSizeChangedTimerFired), | 222 this, |
| 223 &MediaControlsImpl::elementSizeChangedTimerFired), |
216 m_keepShowingUntilTimerFires(false) { | 224 m_keepShowingUntilTimerFires(false) { |
217 m_resizeObserver->observe(m_mediaElement); | 225 m_resizeObserver->observe(&mediaElement); |
218 } | 226 } |
219 | 227 |
220 MediaControls* MediaControls::create(HTMLMediaElement& mediaElement, | 228 MediaControlsImpl* MediaControlsImpl::create(HTMLMediaElement& mediaElement, |
221 ShadowRoot& shadowRoot) { | 229 ShadowRoot& shadowRoot) { |
222 MediaControls* controls = new MediaControls(mediaElement); | 230 MediaControlsImpl* controls = new MediaControlsImpl(mediaElement); |
223 controls->setShadowPseudoId(AtomicString("-webkit-media-controls")); | 231 controls->setShadowPseudoId(AtomicString("-webkit-media-controls")); |
224 controls->initializeControls(); | 232 controls->initializeControls(); |
225 controls->reset(); | 233 controls->reset(); |
226 | 234 |
227 // Initialize the orientation lock when going fullscreen feature. | 235 // Initialize the orientation lock when going fullscreen feature. |
228 if (RuntimeEnabledFeatures::videoFullscreenOrientationLockEnabled() && | 236 if (RuntimeEnabledFeatures::videoFullscreenOrientationLockEnabled() && |
229 mediaElement.isHTMLVideoElement()) { | 237 mediaElement.isHTMLVideoElement()) { |
230 controls->m_orientationLockDelegate = | 238 controls->m_orientationLockDelegate = |
231 new MediaControlsOrientationLockDelegate( | 239 new MediaControlsOrientationLockDelegate( |
232 toHTMLVideoElement(mediaElement)); | 240 toHTMLVideoElement(mediaElement)); |
233 } | 241 } |
234 | 242 |
235 shadowRoot.appendChild(controls); | 243 shadowRoot.appendChild(controls); |
236 return controls; | 244 return controls; |
237 } | 245 } |
238 | 246 |
239 // The media controls DOM structure looks like: | 247 // The media controls DOM structure looks like: |
240 // | 248 // |
241 // MediaControls | 249 // MediaControlsImpl |
242 // (-webkit-media-controls) | 250 // (-webkit-media-controls) |
243 // +-MediaControlOverlayEnclosureElement | 251 // +-MediaControlOverlayEnclosureElement |
244 // | (-webkit-media-controls-overlay-enclosure) | 252 // | (-webkit-media-controls-overlay-enclosure) |
245 // | +-MediaControlOverlayPlayButtonElement | 253 // | +-MediaControlOverlayPlayButtonElement |
246 // | | (-webkit-media-controls-overlay-play-button) | 254 // | | (-webkit-media-controls-overlay-play-button) |
247 // | | {if mediaControlsOverlayPlayButtonEnabled} | 255 // | | {if mediaControlsOverlayPlayButtonEnabled} |
248 // | \-MediaControlCastButtonElement | 256 // | \-MediaControlCastButtonElement |
249 // | (-internal-media-controls-overlay-cast-button) | 257 // | (-internal-media-controls-overlay-cast-button) |
250 // \-MediaControlPanelEnclosureElement | 258 // \-MediaControlPanelEnclosureElement |
251 // | (-webkit-media-controls-enclosure) | 259 // | (-webkit-media-controls-enclosure) |
(...skipping 23 matching lines...) Expand all Loading... |
275 // | (-internal-media-controls-text-track-list) | 283 // | (-internal-media-controls-text-track-list) |
276 // | {for each renderable text track} | 284 // | {for each renderable text track} |
277 // \-MediaControlTextTrackListItem | 285 // \-MediaControlTextTrackListItem |
278 // | (-internal-media-controls-text-track-list-item) | 286 // | (-internal-media-controls-text-track-list-item) |
279 // +-MediaControlTextTrackListItemInput | 287 // +-MediaControlTextTrackListItemInput |
280 // | (-internal-media-controls-text-track-list-item-input) | 288 // | (-internal-media-controls-text-track-list-item-input) |
281 // +-MediaControlTextTrackListItemCaptions | 289 // +-MediaControlTextTrackListItemCaptions |
282 // | (-internal-media-controls-text-track-list-kind-captions) | 290 // | (-internal-media-controls-text-track-list-kind-captions) |
283 // +-MediaControlTextTrackListItemSubtitles | 291 // +-MediaControlTextTrackListItemSubtitles |
284 // (-internal-media-controls-text-track-list-kind-subtitles) | 292 // (-internal-media-controls-text-track-list-kind-subtitles) |
285 void MediaControls::initializeControls() { | 293 void MediaControlsImpl::initializeControls() { |
286 MediaControlOverlayEnclosureElement* overlayEnclosure = | 294 MediaControlOverlayEnclosureElement* overlayEnclosure = |
287 MediaControlOverlayEnclosureElement::create(*this); | 295 MediaControlOverlayEnclosureElement::create(*this); |
288 | 296 |
289 if (RuntimeEnabledFeatures::mediaControlsOverlayPlayButtonEnabled()) { | 297 if (RuntimeEnabledFeatures::mediaControlsOverlayPlayButtonEnabled()) { |
290 MediaControlOverlayPlayButtonElement* overlayPlayButton = | 298 MediaControlOverlayPlayButtonElement* overlayPlayButton = |
291 MediaControlOverlayPlayButtonElement::create(*this); | 299 MediaControlOverlayPlayButtonElement::create(*this); |
292 m_overlayPlayButton = overlayPlayButton; | 300 m_overlayPlayButton = overlayPlayButton; |
293 overlayEnclosure->appendChild(overlayPlayButton); | 301 overlayEnclosure->appendChild(overlayPlayButton); |
294 } | 302 } |
295 | 303 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 *this, MediaControlDownloadButtonElement::create(*this))); | 402 *this, MediaControlDownloadButtonElement::create(*this))); |
395 m_overflowList->appendChild(m_muteButton->createOverflowElement( | 403 m_overflowList->appendChild(m_muteButton->createOverflowElement( |
396 *this, MediaControlMuteButtonElement::create(*this))); | 404 *this, MediaControlMuteButtonElement::create(*this))); |
397 m_overflowList->appendChild(m_castButton->createOverflowElement( | 405 m_overflowList->appendChild(m_castButton->createOverflowElement( |
398 *this, MediaControlCastButtonElement::create(*this, false))); | 406 *this, MediaControlCastButtonElement::create(*this, false))); |
399 m_overflowList->appendChild( | 407 m_overflowList->appendChild( |
400 m_toggleClosedCaptionsButton->createOverflowElement( | 408 m_toggleClosedCaptionsButton->createOverflowElement( |
401 *this, MediaControlToggleClosedCaptionsButtonElement::create(*this))); | 409 *this, MediaControlToggleClosedCaptionsButtonElement::create(*this))); |
402 } | 410 } |
403 | 411 |
404 Node::InsertionNotificationRequest MediaControls::insertedInto( | 412 Node::InsertionNotificationRequest MediaControlsImpl::insertedInto( |
405 ContainerNode* root) { | 413 ContainerNode* root) { |
406 if (!mediaElement().isConnected()) | 414 if (!mediaElement().isConnected()) |
407 return HTMLDivElement::insertedInto(root); | 415 return HTMLDivElement::insertedInto(root); |
408 | 416 |
409 // TODO(mlamouri): we should show the controls instead of having | 417 // TODO(mlamouri): we should show the controls instead of having |
410 // HTMLMediaElement do it. | 418 // HTMLMediaElement do it. |
411 | 419 |
412 // m_windowEventListener doesn't need to be re-attached as it's only needed | 420 // m_windowEventListener doesn't need to be re-attached as it's only needed |
413 // when a menu is visible. | 421 // when a menu is visible. |
414 m_mediaEventListener->attach(); | 422 m_mediaEventListener->attach(); |
415 if (m_orientationLockDelegate) | 423 if (m_orientationLockDelegate) |
416 m_orientationLockDelegate->attach(); | 424 m_orientationLockDelegate->attach(); |
417 | 425 |
418 if (!m_resizeObserver) { | 426 if (!m_resizeObserver) { |
419 m_resizeObserver = | 427 m_resizeObserver = |
420 ResizeObserver::create(m_mediaElement->document(), | 428 ResizeObserver::create(mediaElement().document(), |
421 new MediaControlsResizeObserverCallback(this)); | 429 new MediaControlsResizeObserverCallback(this)); |
422 m_resizeObserver->observe(m_mediaElement); | 430 HTMLMediaElement& htmlMediaElement = mediaElement(); |
| 431 m_resizeObserver->observe(&htmlMediaElement); |
423 } | 432 } |
424 | 433 |
425 return HTMLDivElement::insertedInto(root); | 434 return HTMLDivElement::insertedInto(root); |
426 } | 435 } |
427 | 436 |
428 void MediaControls::removedFrom(ContainerNode*) { | 437 void MediaControlsImpl::removedFrom(ContainerNode*) { |
429 DCHECK(!mediaElement().isConnected()); | 438 DCHECK(!mediaElement().isConnected()); |
430 | 439 |
431 // TODO(mlamouri): we hide show the controls instead of having | 440 // TODO(mlamouri): we hide show the controls instead of having |
432 // HTMLMediaElement do it. | 441 // HTMLMediaElement do it. |
433 | 442 |
434 m_windowEventListener->stop(); | 443 m_windowEventListener->stop(); |
435 m_mediaEventListener->detach(); | 444 m_mediaEventListener->detach(); |
436 if (m_orientationLockDelegate) | 445 if (m_orientationLockDelegate) |
437 m_orientationLockDelegate->detach(); | 446 m_orientationLockDelegate->detach(); |
438 | 447 |
439 m_resizeObserver.clear(); | 448 m_resizeObserver.clear(); |
440 } | 449 } |
441 | 450 |
442 void MediaControls::reset() { | 451 void MediaControlsImpl::reset() { |
443 EventDispatchForbiddenScope::AllowUserAgentEvents allowEventsInShadow; | 452 EventDispatchForbiddenScope::AllowUserAgentEvents allowEventsInShadow; |
444 BatchedControlUpdate batch(this); | 453 BatchedControlUpdate batch(this); |
445 | 454 |
446 const double duration = mediaElement().duration(); | 455 const double duration = mediaElement().duration(); |
447 m_durationDisplay->setTextContent( | 456 m_durationDisplay->setTextContent( |
448 LayoutTheme::theme().formatMediaControlsTime(duration)); | 457 LayoutTheme::theme().formatMediaControlsTime(duration)); |
449 m_durationDisplay->setCurrentValue(duration); | 458 m_durationDisplay->setCurrentValue(duration); |
450 | 459 |
451 // Show everything that we might hide. | 460 // Show everything that we might hide. |
452 // If we don't have a duration, then mark it to be hidden. For the | 461 // If we don't have a duration, then mark it to be hidden. For the |
(...skipping 13 matching lines...) Expand all Loading... |
466 | 475 |
467 m_timeline->setDuration(duration); | 476 m_timeline->setDuration(duration); |
468 m_timeline->setPosition(mediaElement().currentTime()); | 477 m_timeline->setPosition(mediaElement().currentTime()); |
469 | 478 |
470 onVolumeChange(); | 479 onVolumeChange(); |
471 onTextTracksAddedOrRemoved(); | 480 onTextTracksAddedOrRemoved(); |
472 | 481 |
473 onControlsListUpdated(); | 482 onControlsListUpdated(); |
474 } | 483 } |
475 | 484 |
476 void MediaControls::onControlsListUpdated() { | 485 void MediaControlsImpl::onControlsListUpdated() { |
477 BatchedControlUpdate batch(this); | 486 BatchedControlUpdate batch(this); |
478 | 487 |
479 m_fullscreenButton->setIsWanted(shouldShowFullscreenButton(mediaElement())); | 488 m_fullscreenButton->setIsWanted(shouldShowFullscreenButton(mediaElement())); |
480 | 489 |
481 refreshCastButtonVisibilityWithoutUpdate(); | 490 refreshCastButtonVisibilityWithoutUpdate(); |
482 | 491 |
483 m_downloadButton->setIsWanted( | 492 m_downloadButton->setIsWanted( |
484 m_downloadButton->shouldDisplayDownloadButton()); | 493 m_downloadButton->shouldDisplayDownloadButton()); |
485 } | 494 } |
486 | 495 |
487 LayoutObject* MediaControls::layoutObjectForTextTrackLayout() { | 496 LayoutObject* MediaControlsImpl::panelLayoutObject() { |
488 return m_panel->layoutObject(); | 497 return m_panel->layoutObject(); |
489 } | 498 } |
490 | 499 |
491 void MediaControls::show() { | 500 LayoutObject* MediaControlsImpl::containerLayoutObject() { |
| 501 return layoutObject(); |
| 502 } |
| 503 |
| 504 void MediaControlsImpl::show() { |
492 makeOpaque(); | 505 makeOpaque(); |
493 m_panel->setIsWanted(true); | 506 m_panel->setIsWanted(true); |
494 m_panel->setIsDisplayed(true); | 507 m_panel->setIsDisplayed(true); |
495 if (m_overlayPlayButton) | 508 if (m_overlayPlayButton) |
496 m_overlayPlayButton->updateDisplayType(); | 509 m_overlayPlayButton->updateDisplayType(); |
497 } | 510 } |
498 | 511 |
499 void MediaControls::hide() { | 512 void MediaControlsImpl::hide() { |
500 m_panel->setIsWanted(false); | 513 m_panel->setIsWanted(false); |
501 m_panel->setIsDisplayed(false); | 514 m_panel->setIsDisplayed(false); |
502 if (m_overlayPlayButton) | 515 if (m_overlayPlayButton) |
503 m_overlayPlayButton->setIsWanted(false); | 516 m_overlayPlayButton->setIsWanted(false); |
504 } | 517 } |
505 | 518 |
506 bool MediaControls::isVisible() const { | 519 bool MediaControlsImpl::isVisible() const { |
507 return m_panel->isOpaque(); | 520 return m_panel->isOpaque(); |
508 } | 521 } |
509 | 522 |
510 void MediaControls::makeOpaque() { | 523 void MediaControlsImpl::makeOpaque() { |
511 m_panel->makeOpaque(); | 524 m_panel->makeOpaque(); |
512 } | 525 } |
513 | 526 |
514 void MediaControls::makeTransparent() { | 527 void MediaControlsImpl::makeTransparent() { |
515 m_panel->makeTransparent(); | 528 m_panel->makeTransparent(); |
516 } | 529 } |
517 | 530 |
518 bool MediaControls::shouldHideMediaControls(unsigned behaviorFlags) const { | 531 bool MediaControlsImpl::shouldHideMediaControls(unsigned behaviorFlags) const { |
519 // Never hide for a media element without visual representation. | 532 // Never hide for a media element without visual representation. |
520 if (!mediaElement().isHTMLVideoElement() || !mediaElement().hasVideo() || | 533 if (!mediaElement().isHTMLVideoElement() || !mediaElement().hasVideo() || |
521 mediaElement().isPlayingRemotely()) { | 534 mediaElement().isPlayingRemotely()) { |
522 return false; | 535 return false; |
523 } | 536 } |
524 | 537 |
525 // Keep the controls visible as long as the timer is running. | 538 // Keep the controls visible as long as the timer is running. |
526 const bool ignoreWaitForTimer = behaviorFlags & IgnoreWaitForTimer; | 539 const bool ignoreWaitForTimer = behaviorFlags & IgnoreWaitForTimer; |
527 if (!ignoreWaitForTimer && m_keepShowingUntilTimerFires) | 540 if (!ignoreWaitForTimer && m_keepShowingUntilTimerFires) |
528 return false; | 541 return false; |
(...skipping 17 matching lines...) Expand all Loading... |
546 return false; | 559 return false; |
547 } | 560 } |
548 | 561 |
549 // Don't hide the media controls when a panel is showing. | 562 // Don't hide the media controls when a panel is showing. |
550 if (m_textTrackList->isWanted() || m_overflowList->isWanted()) | 563 if (m_textTrackList->isWanted() || m_overflowList->isWanted()) |
551 return false; | 564 return false; |
552 | 565 |
553 return true; | 566 return true; |
554 } | 567 } |
555 | 568 |
556 void MediaControls::updatePlayState() { | 569 void MediaControlsImpl::updatePlayState() { |
557 if (m_isPausedForScrubbing) | 570 if (m_isPausedForScrubbing) |
558 return; | 571 return; |
559 | 572 |
560 if (m_overlayPlayButton) | 573 if (m_overlayPlayButton) |
561 m_overlayPlayButton->updateDisplayType(); | 574 m_overlayPlayButton->updateDisplayType(); |
562 m_playButton->updateDisplayType(); | 575 m_playButton->updateDisplayType(); |
563 } | 576 } |
564 | 577 |
565 void MediaControls::beginScrubbing() { | 578 void MediaControlsImpl::beginScrubbing() { |
566 if (!mediaElement().paused()) { | 579 if (!mediaElement().paused()) { |
567 m_isPausedForScrubbing = true; | 580 m_isPausedForScrubbing = true; |
568 mediaElement().pause(); | 581 mediaElement().pause(); |
569 } | 582 } |
570 } | 583 } |
571 | 584 |
572 void MediaControls::endScrubbing() { | 585 void MediaControlsImpl::endScrubbing() { |
573 if (m_isPausedForScrubbing) { | 586 if (m_isPausedForScrubbing) { |
574 m_isPausedForScrubbing = false; | 587 m_isPausedForScrubbing = false; |
575 if (mediaElement().paused()) | 588 if (mediaElement().paused()) |
576 mediaElement().play(); | 589 mediaElement().play(); |
577 } | 590 } |
578 } | 591 } |
579 | 592 |
580 void MediaControls::updateCurrentTimeDisplay() { | 593 void MediaControlsImpl::updateCurrentTimeDisplay() { |
581 double now = mediaElement().currentTime(); | 594 double now = mediaElement().currentTime(); |
582 double duration = mediaElement().duration(); | 595 double duration = mediaElement().duration(); |
583 | 596 |
584 // Allow the theme to format the time. | 597 // Allow the theme to format the time. |
585 m_currentTimeDisplay->setInnerText( | 598 m_currentTimeDisplay->setInnerText( |
586 LayoutTheme::theme().formatMediaControlsCurrentTime(now, duration), | 599 LayoutTheme::theme().formatMediaControlsCurrentTime(now, duration), |
587 IGNORE_EXCEPTION_FOR_TESTING); | 600 IGNORE_EXCEPTION_FOR_TESTING); |
588 m_currentTimeDisplay->setCurrentValue(now); | 601 m_currentTimeDisplay->setCurrentValue(now); |
589 } | 602 } |
590 | 603 |
591 void MediaControls::toggleTextTrackList() { | 604 void MediaControlsImpl::toggleTextTrackList() { |
592 if (!mediaElement().hasClosedCaptions()) { | 605 if (!mediaElement().hasClosedCaptions()) { |
593 m_textTrackList->setVisible(false); | 606 m_textTrackList->setVisible(false); |
594 return; | 607 return; |
595 } | 608 } |
596 | 609 |
597 if (!m_textTrackList->isWanted()) | 610 if (!m_textTrackList->isWanted()) |
598 m_windowEventListener->start(); | 611 m_windowEventListener->start(); |
599 | 612 |
600 m_textTrackList->setVisible(!m_textTrackList->isWanted()); | 613 m_textTrackList->setVisible(!m_textTrackList->isWanted()); |
601 } | 614 } |
602 | 615 |
603 void MediaControls::showTextTrackAtIndex(unsigned indexToEnable) { | 616 void MediaControlsImpl::showTextTrackAtIndex(unsigned indexToEnable) { |
604 TextTrackList* trackList = mediaElement().textTracks(); | 617 TextTrackList* trackList = mediaElement().textTracks(); |
605 if (indexToEnable >= trackList->length()) | 618 if (indexToEnable >= trackList->length()) |
606 return; | 619 return; |
607 TextTrack* track = trackList->anonymousIndexedGetter(indexToEnable); | 620 TextTrack* track = trackList->anonymousIndexedGetter(indexToEnable); |
608 if (track && track->canBeRendered()) | 621 if (track && track->canBeRendered()) |
609 track->setMode(TextTrack::showingKeyword()); | 622 track->setMode(TextTrack::showingKeyword()); |
610 } | 623 } |
611 | 624 |
612 void MediaControls::disableShowingTextTracks() { | 625 void MediaControlsImpl::disableShowingTextTracks() { |
613 TextTrackList* trackList = mediaElement().textTracks(); | 626 TextTrackList* trackList = mediaElement().textTracks(); |
614 for (unsigned i = 0; i < trackList->length(); ++i) { | 627 for (unsigned i = 0; i < trackList->length(); ++i) { |
615 TextTrack* track = trackList->anonymousIndexedGetter(i); | 628 TextTrack* track = trackList->anonymousIndexedGetter(i); |
616 if (track->mode() == TextTrack::showingKeyword()) | 629 if (track->mode() == TextTrack::showingKeyword()) |
617 track->setMode(TextTrack::disabledKeyword()); | 630 track->setMode(TextTrack::disabledKeyword()); |
618 } | 631 } |
619 } | 632 } |
620 | 633 |
621 void MediaControls::refreshCastButtonVisibility() { | 634 void MediaControlsImpl::refreshCastButtonVisibility() { |
622 refreshCastButtonVisibilityWithoutUpdate(); | 635 refreshCastButtonVisibilityWithoutUpdate(); |
623 BatchedControlUpdate batch(this); | 636 BatchedControlUpdate batch(this); |
624 } | 637 } |
625 | 638 |
626 void MediaControls::refreshCastButtonVisibilityWithoutUpdate() { | 639 void MediaControlsImpl::refreshCastButtonVisibilityWithoutUpdate() { |
627 if (!shouldShowCastButton(mediaElement())) { | 640 if (!shouldShowCastButton(mediaElement())) { |
628 m_castButton->setIsWanted(false); | 641 m_castButton->setIsWanted(false); |
629 m_overlayCastButton->setIsWanted(false); | 642 m_overlayCastButton->setIsWanted(false); |
630 return; | 643 return; |
631 } | 644 } |
632 | 645 |
633 // The reason for the autoplay test is that some pages (e.g. vimeo.com) have | 646 // The reason for the autoplay test is that some pages (e.g. vimeo.com) have |
634 // an autoplay background video, which doesn't autoplay on Chrome for Android | 647 // an autoplay background video, which doesn't autoplay on Chrome for Android |
635 // (we prevent it) so starts paused. In such cases we don't want to | 648 // (we prevent it) so starts paused. In such cases we don't want to |
636 // automatically show the cast button, since it looks strange and is unlikely | 649 // automatically show the cast button, since it looks strange and is unlikely |
(...skipping 11 matching lines...) Expand all Loading... |
648 // is shown, however, compute...() will take control of the | 661 // is shown, however, compute...() will take control of the |
649 // overlay cast button if it needs to hide it from the panel. | 662 // overlay cast button if it needs to hide it from the panel. |
650 m_overlayCastButton->tryShowOverlay(); | 663 m_overlayCastButton->tryShowOverlay(); |
651 m_castButton->setIsWanted(false); | 664 m_castButton->setIsWanted(false); |
652 } else if (mediaElement().shouldShowControls()) { | 665 } else if (mediaElement().shouldShowControls()) { |
653 m_overlayCastButton->setIsWanted(false); | 666 m_overlayCastButton->setIsWanted(false); |
654 m_castButton->setIsWanted(true); | 667 m_castButton->setIsWanted(true); |
655 } | 668 } |
656 } | 669 } |
657 | 670 |
658 void MediaControls::showOverlayCastButtonIfNeeded() { | 671 void MediaControlsImpl::showOverlayCastButtonIfNeeded() { |
659 if (mediaElement().shouldShowControls() || | 672 if (mediaElement().shouldShowControls() || |
660 !shouldShowCastButton(mediaElement())) | 673 !shouldShowCastButton(mediaElement())) |
661 return; | 674 return; |
662 | 675 |
663 m_overlayCastButton->tryShowOverlay(); | 676 m_overlayCastButton->tryShowOverlay(); |
664 resetHideMediaControlsTimer(); | 677 resetHideMediaControlsTimer(); |
665 } | 678 } |
666 | 679 |
667 void MediaControls::enterFullscreen() { | 680 void MediaControlsImpl::enterFullscreen() { |
668 Fullscreen::requestFullscreen(mediaElement()); | 681 Fullscreen::requestFullscreen(mediaElement()); |
669 } | 682 } |
670 | 683 |
671 void MediaControls::exitFullscreen() { | 684 void MediaControlsImpl::exitFullscreen() { |
672 Fullscreen::exitFullscreen(document()); | 685 Fullscreen::exitFullscreen(document()); |
673 } | 686 } |
674 | 687 |
675 void MediaControls::startedCasting() { | 688 void MediaControlsImpl::startedCasting() { |
676 m_castButton->setIsPlayingRemotely(true); | 689 m_castButton->setIsPlayingRemotely(true); |
677 m_overlayCastButton->setIsPlayingRemotely(true); | 690 m_overlayCastButton->setIsPlayingRemotely(true); |
678 } | 691 } |
679 | 692 |
680 void MediaControls::stoppedCasting() { | 693 void MediaControlsImpl::stoppedCasting() { |
681 m_castButton->setIsPlayingRemotely(false); | 694 m_castButton->setIsPlayingRemotely(false); |
682 m_overlayCastButton->setIsPlayingRemotely(false); | 695 m_overlayCastButton->setIsPlayingRemotely(false); |
683 } | 696 } |
684 | 697 |
685 void MediaControls::defaultEventHandler(Event* event) { | 698 void MediaControlsImpl::defaultEventHandler(Event* event) { |
686 HTMLDivElement::defaultEventHandler(event); | 699 HTMLDivElement::defaultEventHandler(event); |
687 | 700 |
688 // Do not handle events to not interfere with the rest of the page if no | 701 // Do not handle events to not interfere with the rest of the page if no |
689 // controls should be visible. | 702 // controls should be visible. |
690 if (!mediaElement().shouldShowControls()) | 703 if (!mediaElement().shouldShowControls()) |
691 return; | 704 return; |
692 | 705 |
693 // Add IgnoreControlsHover to m_hideTimerBehaviorFlags when we see a touch | 706 // Add IgnoreControlsHover to m_hideTimerBehaviorFlags when we see a touch |
694 // event, to allow the hide-timer to do the right thing when it fires. | 707 // event, to allow the hide-timer to do the right thing when it fires. |
695 // FIXME: Preferably we would only do this when we're actually handling the | 708 // FIXME: Preferably we would only do this when we're actually handling the |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 if (event->type() == EventTypeNames::mousemove) { | 760 if (event->type() == EventTypeNames::mousemove) { |
748 // When we get a mouse move, show the media controls, and start a timer | 761 // When we get a mouse move, show the media controls, and start a timer |
749 // that will hide the media controls after a 3 seconds without a mouse move. | 762 // that will hide the media controls after a 3 seconds without a mouse move. |
750 makeOpaque(); | 763 makeOpaque(); |
751 if (shouldHideMediaControls(IgnoreVideoHover)) | 764 if (shouldHideMediaControls(IgnoreVideoHover)) |
752 startHideMediaControlsTimer(); | 765 startHideMediaControlsTimer(); |
753 return; | 766 return; |
754 } | 767 } |
755 } | 768 } |
756 | 769 |
757 void MediaControls::hideMediaControlsTimerFired(TimerBase*) { | 770 void MediaControlsImpl::hideMediaControlsTimerFired(TimerBase*) { |
758 unsigned behaviorFlags = | 771 unsigned behaviorFlags = |
759 m_hideTimerBehaviorFlags | IgnoreFocus | IgnoreVideoHover; | 772 m_hideTimerBehaviorFlags | IgnoreFocus | IgnoreVideoHover; |
760 m_hideTimerBehaviorFlags = IgnoreNone; | 773 m_hideTimerBehaviorFlags = IgnoreNone; |
761 m_keepShowingUntilTimerFires = false; | 774 m_keepShowingUntilTimerFires = false; |
762 | 775 |
763 if (mediaElement().paused()) | 776 if (mediaElement().paused()) |
764 return; | 777 return; |
765 | 778 |
766 if (!shouldHideMediaControls(behaviorFlags)) | 779 if (!shouldHideMediaControls(behaviorFlags)) |
767 return; | 780 return; |
768 | 781 |
769 makeTransparent(); | 782 makeTransparent(); |
770 m_overlayCastButton->setIsWanted(false); | 783 m_overlayCastButton->setIsWanted(false); |
771 } | 784 } |
772 | 785 |
773 void MediaControls::startHideMediaControlsTimer() { | 786 void MediaControlsImpl::startHideMediaControlsTimer() { |
774 m_hideMediaControlsTimer.startOneShot( | 787 m_hideMediaControlsTimer.startOneShot( |
775 timeWithoutMouseMovementBeforeHidingMediaControls, BLINK_FROM_HERE); | 788 timeWithoutMouseMovementBeforeHidingMediaControls, BLINK_FROM_HERE); |
776 } | 789 } |
777 | 790 |
778 void MediaControls::stopHideMediaControlsTimer() { | 791 void MediaControlsImpl::stopHideMediaControlsTimer() { |
779 m_keepShowingUntilTimerFires = false; | 792 m_keepShowingUntilTimerFires = false; |
780 m_hideMediaControlsTimer.stop(); | 793 m_hideMediaControlsTimer.stop(); |
781 } | 794 } |
782 | 795 |
783 void MediaControls::resetHideMediaControlsTimer() { | 796 void MediaControlsImpl::resetHideMediaControlsTimer() { |
784 stopHideMediaControlsTimer(); | 797 stopHideMediaControlsTimer(); |
785 if (!mediaElement().paused()) | 798 if (!mediaElement().paused()) |
786 startHideMediaControlsTimer(); | 799 startHideMediaControlsTimer(); |
787 } | 800 } |
788 | 801 |
789 bool MediaControls::containsRelatedTarget(Event* event) { | 802 bool MediaControlsImpl::containsRelatedTarget(Event* event) { |
790 if (!event->isMouseEvent()) | 803 if (!event->isMouseEvent()) |
791 return false; | 804 return false; |
792 EventTarget* relatedTarget = toMouseEvent(event)->relatedTarget(); | 805 EventTarget* relatedTarget = toMouseEvent(event)->relatedTarget(); |
793 if (!relatedTarget) | 806 if (!relatedTarget) |
794 return false; | 807 return false; |
795 return contains(relatedTarget->toNode()); | 808 return contains(relatedTarget->toNode()); |
796 } | 809 } |
797 | 810 |
798 void MediaControls::onVolumeChange() { | 811 void MediaControlsImpl::onVolumeChange() { |
799 m_muteButton->updateDisplayType(); | 812 m_muteButton->updateDisplayType(); |
800 m_volumeSlider->setVolume(mediaElement().muted() ? 0 | 813 m_volumeSlider->setVolume(mediaElement().muted() ? 0 |
801 : mediaElement().volume()); | 814 : mediaElement().volume()); |
802 | 815 |
803 // Update visibility of volume controls. | 816 // Update visibility of volume controls. |
804 // TODO(mlamouri): it should not be part of the volumechange handling because | 817 // TODO(mlamouri): it should not be part of the volumechange handling because |
805 // it is using audio availability as input. | 818 // it is using audio availability as input. |
806 BatchedControlUpdate batch(this); | 819 BatchedControlUpdate batch(this); |
807 m_volumeSlider->setIsWanted(mediaElement().hasAudio() && | 820 m_volumeSlider->setIsWanted(mediaElement().hasAudio() && |
808 !preferHiddenVolumeControls(document())); | 821 !preferHiddenVolumeControls(document())); |
809 m_muteButton->setIsWanted(mediaElement().hasAudio()); | 822 m_muteButton->setIsWanted(mediaElement().hasAudio()); |
810 } | 823 } |
811 | 824 |
812 void MediaControls::onFocusIn() { | 825 void MediaControlsImpl::onFocusIn() { |
813 if (!mediaElement().shouldShowControls()) | 826 if (!mediaElement().shouldShowControls()) |
814 return; | 827 return; |
815 | 828 |
816 show(); | 829 show(); |
817 resetHideMediaControlsTimer(); | 830 resetHideMediaControlsTimer(); |
818 } | 831 } |
819 | 832 |
820 void MediaControls::onTimeUpdate() { | 833 void MediaControlsImpl::onTimeUpdate() { |
821 m_timeline->setPosition(mediaElement().currentTime()); | 834 m_timeline->setPosition(mediaElement().currentTime()); |
822 updateCurrentTimeDisplay(); | 835 updateCurrentTimeDisplay(); |
823 | 836 |
824 // 'timeupdate' might be called in a paused state. The controls should not | 837 // 'timeupdate' might be called in a paused state. The controls should not |
825 // become transparent in that case. | 838 // become transparent in that case. |
826 if (mediaElement().paused()) { | 839 if (mediaElement().paused()) { |
827 makeOpaque(); | 840 makeOpaque(); |
828 return; | 841 return; |
829 } | 842 } |
830 | 843 |
831 if (isVisible() && shouldHideMediaControls()) | 844 if (isVisible() && shouldHideMediaControls()) |
832 makeTransparent(); | 845 makeTransparent(); |
833 } | 846 } |
834 | 847 |
835 void MediaControls::onDurationChange() { | 848 void MediaControlsImpl::onDurationChange() { |
836 const double duration = mediaElement().duration(); | 849 const double duration = mediaElement().duration(); |
837 | 850 |
838 // Update the displayed current time/duration. | 851 // Update the displayed current time/duration. |
839 m_durationDisplay->setTextContent( | 852 m_durationDisplay->setTextContent( |
840 LayoutTheme::theme().formatMediaControlsTime(duration)); | 853 LayoutTheme::theme().formatMediaControlsTime(duration)); |
841 m_durationDisplay->setCurrentValue(duration); | 854 m_durationDisplay->setCurrentValue(duration); |
842 updateCurrentTimeDisplay(); | 855 updateCurrentTimeDisplay(); |
843 | 856 |
844 // Update the timeline (the UI with the seek marker). | 857 // Update the timeline (the UI with the seek marker). |
845 m_timeline->setDuration(duration); | 858 m_timeline->setDuration(duration); |
846 } | 859 } |
847 | 860 |
848 void MediaControls::onPlay() { | 861 void MediaControlsImpl::onPlay() { |
849 updatePlayState(); | 862 updatePlayState(); |
850 m_timeline->setPosition(mediaElement().currentTime()); | 863 m_timeline->setPosition(mediaElement().currentTime()); |
851 updateCurrentTimeDisplay(); | 864 updateCurrentTimeDisplay(); |
852 | 865 |
853 startHideMediaControlsTimer(); | 866 startHideMediaControlsTimer(); |
854 } | 867 } |
855 | 868 |
856 void MediaControls::onPause() { | 869 void MediaControlsImpl::onPause() { |
857 updatePlayState(); | 870 updatePlayState(); |
858 m_timeline->setPosition(mediaElement().currentTime()); | 871 m_timeline->setPosition(mediaElement().currentTime()); |
859 updateCurrentTimeDisplay(); | 872 updateCurrentTimeDisplay(); |
860 makeOpaque(); | 873 makeOpaque(); |
861 | 874 |
862 stopHideMediaControlsTimer(); | 875 stopHideMediaControlsTimer(); |
863 } | 876 } |
864 | 877 |
865 void MediaControls::onTextTracksAddedOrRemoved() { | 878 void MediaControlsImpl::onTextTracksAddedOrRemoved() { |
866 m_toggleClosedCaptionsButton->setIsWanted(mediaElement().hasClosedCaptions()); | 879 m_toggleClosedCaptionsButton->setIsWanted(mediaElement().hasClosedCaptions()); |
867 BatchedControlUpdate batch(this); | 880 BatchedControlUpdate batch(this); |
868 } | 881 } |
869 | 882 |
870 void MediaControls::onTextTracksChanged() { | 883 void MediaControlsImpl::onTextTracksChanged() { |
871 m_toggleClosedCaptionsButton->updateDisplayType(); | 884 m_toggleClosedCaptionsButton->updateDisplayType(); |
872 } | 885 } |
873 | 886 |
874 void MediaControls::onError() { | 887 void MediaControlsImpl::onError() { |
875 // TODO(mlamouri): we should only change the aspects of the control that need | 888 // TODO(mlamouri): we should only change the aspects of the control that need |
876 // to be changed. | 889 // to be changed. |
877 reset(); | 890 reset(); |
878 } | 891 } |
879 | 892 |
880 void MediaControls::onLoadedMetadata() { | 893 void MediaControlsImpl::onLoadedMetadata() { |
881 // TODO(mlamouri): we should only change the aspects of the control that need | 894 // TODO(mlamouri): we should only change the aspects of the control that need |
882 // to be changed. | 895 // to be changed. |
883 reset(); | 896 reset(); |
884 } | 897 } |
885 | 898 |
886 void MediaControls::onEnteredFullscreen() { | 899 void MediaControlsImpl::onEnteredFullscreen() { |
887 m_fullscreenButton->setIsFullscreen(true); | 900 m_fullscreenButton->setIsFullscreen(true); |
888 stopHideMediaControlsTimer(); | 901 stopHideMediaControlsTimer(); |
889 startHideMediaControlsTimer(); | 902 startHideMediaControlsTimer(); |
890 } | 903 } |
891 | 904 |
892 void MediaControls::onExitedFullscreen() { | 905 void MediaControlsImpl::onExitedFullscreen() { |
893 m_fullscreenButton->setIsFullscreen(false); | 906 m_fullscreenButton->setIsFullscreen(false); |
894 stopHideMediaControlsTimer(); | 907 stopHideMediaControlsTimer(); |
895 startHideMediaControlsTimer(); | 908 startHideMediaControlsTimer(); |
896 } | 909 } |
897 | 910 |
898 void MediaControls::notifyElementSizeChanged(ClientRect* newSize) { | 911 void MediaControlsImpl::notifyElementSizeChanged(ClientRect* newSize) { |
899 // Note that this code permits a bad frame on resize, since it is | 912 // Note that this code permits a bad frame on resize, since it is |
900 // run after the relayout / paint happens. It would be great to improve | 913 // run after the relayout / paint happens. It would be great to improve |
901 // this, but it would be even greater to move this code entirely to | 914 // this, but it would be even greater to move this code entirely to |
902 // JS and fix it there. | 915 // JS and fix it there. |
903 | 916 |
904 IntSize oldSize = m_size; | 917 IntSize oldSize = m_size; |
905 m_size.setWidth(newSize->width()); | 918 m_size.setWidth(newSize->width()); |
906 m_size.setHeight(newSize->height()); | 919 m_size.setHeight(newSize->height()); |
907 | 920 |
908 // Adjust for effective zoom. | 921 // Adjust for effective zoom. |
909 if (m_panel->layoutObject() && m_panel->layoutObject()->style()) { | 922 if (m_panel->layoutObject() && m_panel->layoutObject()->style()) { |
910 m_size.setWidth(ceil(m_size.width() / | 923 m_size.setWidth(ceil(m_size.width() / |
911 m_panel->layoutObject()->style()->effectiveZoom())); | 924 m_panel->layoutObject()->style()->effectiveZoom())); |
912 m_size.setHeight(ceil(m_size.height() / | 925 m_size.setHeight(ceil(m_size.height() / |
913 m_panel->layoutObject()->style()->effectiveZoom())); | 926 m_panel->layoutObject()->style()->effectiveZoom())); |
914 } | 927 } |
915 | 928 |
916 // Don't bother to do any work if this matches the most recent size. | 929 // Don't bother to do any work if this matches the most recent size. |
917 if (oldSize != m_size) | 930 if (oldSize != m_size) |
918 m_elementSizeChangedTimer.startOneShot(0, BLINK_FROM_HERE); | 931 m_elementSizeChangedTimer.startOneShot(0, BLINK_FROM_HERE); |
919 } | 932 } |
920 | 933 |
921 void MediaControls::elementSizeChangedTimerFired(TimerBase*) { | 934 void MediaControlsImpl::elementSizeChangedTimerFired(TimerBase*) { |
922 computeWhichControlsFit(); | 935 computeWhichControlsFit(); |
923 } | 936 } |
924 | 937 |
925 void MediaControls::computeWhichControlsFit() { | 938 void MediaControlsImpl::computeWhichControlsFit() { |
926 // Hide all controls that don't fit, and show the ones that do. | 939 // Hide all controls that don't fit, and show the ones that do. |
927 // This might be better suited for a layout, but since JS media controls | 940 // This might be better suited for a layout, but since JS media controls |
928 // won't benefit from that anwyay, we just do it here like JS will. | 941 // won't benefit from that anwyay, we just do it here like JS will. |
929 | 942 |
930 // Controls that we'll hide / show, in order of decreasing priority. | 943 // Controls that we'll hide / show, in order of decreasing priority. |
931 MediaControlElement* elements[] = { | 944 MediaControlElement* elements[] = { |
932 // Exclude m_overflowMenu; we handle it specially. | 945 // Exclude m_overflowMenu; we handle it specially. |
933 m_playButton.get(), | 946 m_playButton.get(), |
934 m_fullscreenButton.get(), | 947 m_fullscreenButton.get(), |
935 m_downloadButton.get(), | 948 m_downloadButton.get(), |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 } | 1041 } |
1029 | 1042 |
1030 // Decide if the overlay play button fits. | 1043 // Decide if the overlay play button fits. |
1031 if (m_overlayPlayButton) { | 1044 if (m_overlayPlayButton) { |
1032 bool doesFit = m_size.width() >= kMinWidthForOverlayPlayButton && | 1045 bool doesFit = m_size.width() >= kMinWidthForOverlayPlayButton && |
1033 m_size.height() >= kMinHeightForOverlayPlayButton; | 1046 m_size.height() >= kMinHeightForOverlayPlayButton; |
1034 m_overlayPlayButton->setDoesFit(doesFit); | 1047 m_overlayPlayButton->setDoesFit(doesFit); |
1035 } | 1048 } |
1036 } | 1049 } |
1037 | 1050 |
1038 void MediaControls::invalidate(Element* element) { | 1051 void MediaControlsImpl::invalidate(Element* element) { |
1039 if (!element) | 1052 if (!element) |
1040 return; | 1053 return; |
1041 | 1054 |
1042 if (LayoutObject* layoutObject = element->layoutObject()) | 1055 if (LayoutObject* layoutObject = element->layoutObject()) { |
1043 layoutObject | 1056 layoutObject |
1044 ->setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants(); | 1057 ->setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants(); |
| 1058 } |
1045 } | 1059 } |
1046 | 1060 |
1047 void MediaControls::networkStateChanged() { | 1061 void MediaControlsImpl::networkStateChanged() { |
1048 invalidate(m_playButton); | 1062 invalidate(m_playButton); |
1049 invalidate(m_overlayPlayButton); | 1063 invalidate(m_overlayPlayButton); |
1050 invalidate(m_muteButton); | 1064 invalidate(m_muteButton); |
1051 invalidate(m_fullscreenButton); | 1065 invalidate(m_fullscreenButton); |
1052 invalidate(m_downloadButton); | 1066 invalidate(m_downloadButton); |
1053 invalidate(m_timeline); | 1067 invalidate(m_timeline); |
1054 invalidate(m_volumeSlider); | 1068 invalidate(m_volumeSlider); |
1055 | 1069 |
1056 // Update the display state of the download button in case we now have a | 1070 // Update the display state of the download button in case we now have a |
1057 // source or no longer have a source. | 1071 // source or no longer have a source. |
1058 m_downloadButton->setIsWanted( | 1072 m_downloadButton->setIsWanted( |
1059 m_downloadButton->shouldDisplayDownloadButton()); | 1073 m_downloadButton->shouldDisplayDownloadButton()); |
1060 } | 1074 } |
1061 | 1075 |
1062 bool MediaControls::overflowMenuVisible() { | 1076 bool MediaControlsImpl::overflowMenuVisible() { |
1063 return m_overflowList ? m_overflowList->isWanted() : false; | 1077 return m_overflowList ? m_overflowList->isWanted() : false; |
1064 } | 1078 } |
1065 | 1079 |
1066 void MediaControls::toggleOverflowMenu() { | 1080 void MediaControlsImpl::toggleOverflowMenu() { |
1067 DCHECK(m_overflowList); | 1081 DCHECK(m_overflowList); |
1068 | 1082 |
1069 if (!m_overflowList->isWanted()) | 1083 if (!m_overflowList->isWanted()) |
1070 m_windowEventListener->start(); | 1084 m_windowEventListener->start(); |
1071 m_overflowList->setIsWanted(!m_overflowList->isWanted()); | 1085 m_overflowList->setIsWanted(!m_overflowList->isWanted()); |
1072 } | 1086 } |
1073 | 1087 |
1074 void MediaControls::hideAllMenus() { | 1088 void MediaControlsImpl::hideAllMenus() { |
1075 m_windowEventListener->stop(); | 1089 m_windowEventListener->stop(); |
1076 | 1090 |
1077 if (m_overflowList->isWanted()) | 1091 if (m_overflowList->isWanted()) |
1078 m_overflowList->setIsWanted(false); | 1092 m_overflowList->setIsWanted(false); |
1079 if (m_textTrackList->isWanted()) | 1093 if (m_textTrackList->isWanted()) |
1080 m_textTrackList->setVisible(false); | 1094 m_textTrackList->setVisible(false); |
1081 } | 1095 } |
1082 | 1096 |
1083 DEFINE_TRACE(MediaControls) { | 1097 DEFINE_TRACE(MediaControlsImpl) { |
1084 visitor->trace(m_resizeObserver); | 1098 visitor->trace(m_resizeObserver); |
1085 visitor->trace(m_mediaElement); | |
1086 visitor->trace(m_panel); | 1099 visitor->trace(m_panel); |
1087 visitor->trace(m_overlayPlayButton); | 1100 visitor->trace(m_overlayPlayButton); |
1088 visitor->trace(m_overlayEnclosure); | 1101 visitor->trace(m_overlayEnclosure); |
1089 visitor->trace(m_playButton); | 1102 visitor->trace(m_playButton); |
1090 visitor->trace(m_currentTimeDisplay); | 1103 visitor->trace(m_currentTimeDisplay); |
1091 visitor->trace(m_timeline); | 1104 visitor->trace(m_timeline); |
1092 visitor->trace(m_muteButton); | 1105 visitor->trace(m_muteButton); |
1093 visitor->trace(m_volumeSlider); | 1106 visitor->trace(m_volumeSlider); |
1094 visitor->trace(m_toggleClosedCaptionsButton); | 1107 visitor->trace(m_toggleClosedCaptionsButton); |
1095 visitor->trace(m_fullscreenButton); | 1108 visitor->trace(m_fullscreenButton); |
1096 visitor->trace(m_downloadButton); | 1109 visitor->trace(m_downloadButton); |
1097 visitor->trace(m_durationDisplay); | 1110 visitor->trace(m_durationDisplay); |
1098 visitor->trace(m_enclosure); | 1111 visitor->trace(m_enclosure); |
1099 visitor->trace(m_textTrackList); | 1112 visitor->trace(m_textTrackList); |
1100 visitor->trace(m_overflowMenu); | 1113 visitor->trace(m_overflowMenu); |
1101 visitor->trace(m_overflowList); | 1114 visitor->trace(m_overflowList); |
1102 visitor->trace(m_castButton); | 1115 visitor->trace(m_castButton); |
1103 visitor->trace(m_overlayCastButton); | 1116 visitor->trace(m_overlayCastButton); |
1104 visitor->trace(m_mediaEventListener); | 1117 visitor->trace(m_mediaEventListener); |
1105 visitor->trace(m_windowEventListener); | 1118 visitor->trace(m_windowEventListener); |
1106 visitor->trace(m_orientationLockDelegate); | 1119 visitor->trace(m_orientationLockDelegate); |
| 1120 MediaControls::trace(visitor); |
1107 HTMLDivElement::trace(visitor); | 1121 HTMLDivElement::trace(visitor); |
1108 } | 1122 } |
1109 | 1123 |
1110 } // namespace blink | 1124 } // namespace blink |
OLD | NEW |