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 17 matching lines...) Expand all Loading... | |
28 #include "core/html/shadow/MediaControls.h" | 28 #include "core/html/shadow/MediaControls.h" |
29 | 29 |
30 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | 30 #include "bindings/core/v8/ExceptionStatePlaceholder.h" |
31 #include "core/dom/ClientRect.h" | 31 #include "core/dom/ClientRect.h" |
32 #include "core/events/MouseEvent.h" | 32 #include "core/events/MouseEvent.h" |
33 #include "core/frame/Settings.h" | 33 #include "core/frame/Settings.h" |
34 #include "core/html/HTMLMediaElement.h" | 34 #include "core/html/HTMLMediaElement.h" |
35 #include "core/html/MediaController.h" | 35 #include "core/html/MediaController.h" |
36 #include "core/html/track/TextTrackContainer.h" | 36 #include "core/html/track/TextTrackContainer.h" |
37 #include "core/layout/LayoutTheme.h" | 37 #include "core/layout/LayoutTheme.h" |
38 #include "public/platform/Platform.h" | |
philipj_slow
2015/07/08 15:06:38
It doesn't look like this include is needed.
liberato (no reviews please)
2015/07/09 12:10:56
Done.
| |
38 | 39 |
39 namespace blink { | 40 namespace blink { |
40 | 41 |
41 // If you change this value, then also update the corresponding value in | 42 // If you change this value, then also update the corresponding value in |
42 // LayoutTests/media/media-controls.js. | 43 // LayoutTests/media/media-controls.js. |
43 static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3; | 44 static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3; |
44 | 45 |
45 static bool fullscreenIsSupported(const Document& document) | 46 static bool fullscreenIsSupported(const Document& document) |
46 { | 47 { |
47 return !document.settings() || document.settings()->fullscreenSupported(); | 48 return !document.settings() || document.settings()->fullscreenSupported(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 // The media controls DOM structure looks like: | 83 // The media controls DOM structure looks like: |
83 // | 84 // |
84 // MediaControls (-webkit-media-controls) | 85 // MediaControls (-webkit-media-controls) |
85 // +-MediaControlOverlayEnclosureElement (-webkit-media-controls-o verlay-enclosure) | 86 // +-MediaControlOverlayEnclosureElement (-webkit-media-controls-o verlay-enclosure) |
86 // | +-MediaControlOverlayPlayButtonElement (-webkit-media-controls-o verlay-play-button) | 87 // | +-MediaControlOverlayPlayButtonElement (-webkit-media-controls-o verlay-play-button) |
87 // | | {if mediaControlsOverlayPlayButtonEnabled} | 88 // | | {if mediaControlsOverlayPlayButtonEnabled} |
88 // | \-MediaControlCastButtonElement (-internal-media-controls -overlay-cast-button) | 89 // | \-MediaControlCastButtonElement (-internal-media-controls -overlay-cast-button) |
89 // \-MediaControlPanelEnclosureElement (-webkit-media-controls-e nclosure) | 90 // \-MediaControlPanelEnclosureElement (-webkit-media-controls-e nclosure) |
90 // \-MediaControlPanelElement (-webkit-media-controls-p anel) | 91 // \-MediaControlPanelElement (-webkit-media-controls-p anel) |
91 // +-MediaControlPlayButtonElement (-webkit-media-controls-p lay-button) | 92 // +-MediaControlPlayButtonElement (-webkit-media-controls-p lay-button) |
92 // +-MediaControlTimelineElement (-webkit-media-controls-t imeline) | |
93 // +-MediaControlCurrentTimeDisplayElement (-webkit-media-controls-c urrent-time-display) | 93 // +-MediaControlCurrentTimeDisplayElement (-webkit-media-controls-c urrent-time-display) |
94 // +-MediaControlTimeRemainingDisplayElement (-webkit-media-controls-t ime-remaining-display) | 94 // +-MediaControlTimeRemainingDisplayElement (-webkit-media-controls-t ime-remaining-display) |
95 // +-MediaControlTimelineElement (-webkit-media-controls-t imeline) | |
philipj_slow
2015/07/08 15:06:38
Can you keep it in both places and annotated with
liberato (no reviews please)
2015/07/09 12:10:56
Done.
| |
95 // +-MediaControlMuteButtonElement (-webkit-media-controls-m ute-button) | 96 // +-MediaControlMuteButtonElement (-webkit-media-controls-m ute-button) |
96 // +-MediaControlVolumeSliderElement (-webkit-media-controls-v olume-slider) | 97 // +-MediaControlVolumeSliderElement (-webkit-media-controls-v olume-slider) |
97 // +-MediaControlToggleClosedCaptionsButtonElement (-webkit-media-controls-t oggle-closed-captions-button) | 98 // +-MediaControlToggleClosedCaptionsButtonElement (-webkit-media-controls-t oggle-closed-captions-button) |
98 // +-MediaControlCastButtonElement (-internal-media-controls -cast-button) | 99 // +-MediaControlCastButtonElement (-internal-media-controls -cast-button) |
99 // \-MediaControlFullscreenButtonElement (-webkit-media-controls-f ullscreen-button) | 100 // \-MediaControlFullscreenButtonElement (-webkit-media-controls-f ullscreen-button) |
100 void MediaControls::initializeControls() | 101 void MediaControls::initializeControls() |
101 { | 102 { |
102 RefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = M ediaControlOverlayEnclosureElement::create(*this); | 103 RefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = M ediaControlOverlayEnclosureElement::create(*this); |
103 | 104 |
104 if (document().settings() && document().settings()->mediaControlsOverlayPlay ButtonEnabled()) { | 105 if (document().settings() && document().settings()->mediaControlsOverlayPlay ButtonEnabled()) { |
(...skipping 13 matching lines...) Expand all Loading... | |
118 RefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> enclosure = MediaContr olPanelEnclosureElement::create(*this); | 119 RefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> enclosure = MediaContr olPanelEnclosureElement::create(*this); |
119 | 120 |
120 RefPtrWillBeRawPtr<MediaControlPanelElement> panel = MediaControlPanelElemen t::create(*this); | 121 RefPtrWillBeRawPtr<MediaControlPanelElement> panel = MediaControlPanelElemen t::create(*this); |
121 | 122 |
122 RefPtrWillBeRawPtr<MediaControlPlayButtonElement> playButton = MediaControlP layButtonElement::create(*this); | 123 RefPtrWillBeRawPtr<MediaControlPlayButtonElement> playButton = MediaControlP layButtonElement::create(*this); |
123 m_playButton = playButton.get(); | 124 m_playButton = playButton.get(); |
124 panel->appendChild(playButton.release()); | 125 panel->appendChild(playButton.release()); |
125 | 126 |
126 RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = MediaControlTimel ineElement::create(*this); | 127 RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = MediaControlTimel ineElement::create(*this); |
127 m_timeline = timeline.get(); | 128 m_timeline = timeline.get(); |
128 panel->appendChild(timeline.release()); | 129 // In old UX, timeline is before the time / duration text. |
130 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) | |
131 panel->appendChild(timeline.release()); | |
132 // else we will attach it later. | |
129 | 133 |
130 RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(*this); | 134 RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(*this); |
131 m_currentTimeDisplay = currentTimeDisplay.get(); | 135 m_currentTimeDisplay = currentTimeDisplay.get(); |
132 m_currentTimeDisplay->hide(); | 136 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) |
137 m_currentTimeDisplay->dontWant(); | |
138 else | |
139 m_currentTimeDisplay->want(); | |
140 | |
133 panel->appendChild(currentTimeDisplay.release()); | 141 panel->appendChild(currentTimeDisplay.release()); |
134 | 142 |
135 RefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(*this); | 143 RefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(*this); |
136 m_durationDisplay = durationDisplay.get(); | 144 m_durationDisplay = durationDisplay.get(); |
137 panel->appendChild(durationDisplay.release()); | 145 panel->appendChild(durationDisplay.release()); |
138 | 146 |
147 // In new UX, timeline is after the time / duration text. | |
148 if (RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) | |
149 panel->appendChild(timeline.release()); | |
150 | |
139 RefPtrWillBeRawPtr<MediaControlMuteButtonElement> muteButton = MediaControlM uteButtonElement::create(*this); | 151 RefPtrWillBeRawPtr<MediaControlMuteButtonElement> muteButton = MediaControlM uteButtonElement::create(*this); |
140 m_muteButton = muteButton.get(); | 152 m_muteButton = muteButton.get(); |
141 panel->appendChild(muteButton.release()); | 153 panel->appendChild(muteButton.release()); |
154 #if OS(ANDROID) | |
155 if (RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) | |
156 m_muteButton->dontWant(); | |
157 #endif | |
142 | 158 |
143 RefPtrWillBeRawPtr<MediaControlVolumeSliderElement> slider = MediaControlVol umeSliderElement::create(*this); | 159 RefPtrWillBeRawPtr<MediaControlVolumeSliderElement> slider = MediaControlVol umeSliderElement::create(*this); |
144 m_volumeSlider = slider.get(); | 160 m_volumeSlider = slider.get(); |
145 panel->appendChild(slider.release()); | 161 panel->appendChild(slider.release()); |
162 #if OS(ANDROID) | |
163 if (RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) | |
164 m_volumeSlider->dontWant(); | |
165 #endif | |
146 | 166 |
147 RefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClos edCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(*this); | 167 RefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClos edCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(*this); |
148 m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get(); | 168 m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get(); |
149 panel->appendChild(toggleClosedCaptionsButton.release()); | 169 panel->appendChild(toggleClosedCaptionsButton.release()); |
150 | 170 |
151 RefPtrWillBeRawPtr<MediaControlCastButtonElement> castButton = MediaControlC astButtonElement::create(*this, false); | 171 RefPtrWillBeRawPtr<MediaControlCastButtonElement> castButton = MediaControlC astButtonElement::create(*this, false); |
152 m_castButton = castButton.get(); | 172 m_castButton = castButton.get(); |
153 panel->appendChild(castButton.release()); | 173 panel->appendChild(castButton.release()); |
154 | 174 |
155 RefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> fullscreenButton = M ediaControlFullscreenButtonElement::create(*this); | 175 RefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> fullscreenButton = M ediaControlFullscreenButtonElement::create(*this); |
156 m_fullScreenButton = fullscreenButton.get(); | 176 m_fullScreenButton = fullscreenButton.get(); |
157 panel->appendChild(fullscreenButton.release()); | 177 panel->appendChild(fullscreenButton.release()); |
158 | 178 |
159 m_panel = panel.get(); | 179 m_panel = panel.get(); |
160 enclosure->appendChild(panel.release()); | 180 enclosure->appendChild(panel.release()); |
161 | 181 |
162 m_enclosure = enclosure.get(); | 182 m_enclosure = enclosure.get(); |
163 appendChild(enclosure.release()); | 183 appendChild(enclosure.release()); |
164 } | 184 } |
165 | 185 |
166 void MediaControls::reset() | 186 void MediaControls::reset() |
167 { | 187 { |
188 const bool useNewUi = RuntimeEnabledFeatures::newMediaPlaybackUiEnabled(); | |
168 double duration = mediaElement().duration(); | 189 double duration = mediaElement().duration(); |
169 m_durationDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsTime (duration), ASSERT_NO_EXCEPTION); | 190 m_durationDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsTime (duration), ASSERT_NO_EXCEPTION); |
170 m_durationDisplay->setCurrentValue(duration); | 191 m_durationDisplay->setCurrentValue(duration); |
171 | 192 |
193 if (useNewUi) { | |
194 // Show everything that we might hide. | |
195 // If we don't have a duration, then mark it to be hidden by | |
196 // scheduleUpdateControlsVisibilityForSpace(). For the old UI case, we still | |
197 // hide / show it here, too, since update*() won't. | |
198 if (std::isfinite(duration)) | |
199 m_durationDisplay->want(); | |
200 else | |
201 m_durationDisplay->dontWant(); | |
202 m_currentTimeDisplay->want(); | |
203 m_timeline->want(); | |
204 } | |
205 | |
172 updatePlayState(); | 206 updatePlayState(); |
173 | 207 |
174 updateCurrentTimeDisplay(); | 208 updateCurrentTimeDisplay(); |
175 | 209 |
176 m_timeline->setDuration(duration); | 210 m_timeline->setDuration(duration); |
177 m_timeline->setPosition(mediaElement().currentTime()); | 211 m_timeline->setPosition(mediaElement().currentTime()); |
178 | 212 |
179 if (!mediaElement().hasAudio()) | 213 if (!mediaElement().hasAudio()) { |
180 m_volumeSlider->hide(); | 214 m_volumeSlider->dontWant(); |
181 else | 215 } else { |
182 m_volumeSlider->show(); | 216 #if OS(ANDROID) |
217 // New UI always hides the volume slider on Android. | |
218 if (useNewUi) | |
219 m_volumeSlider->dontWant(); | |
220 else | |
221 m_volumeSlider->want(); | |
222 #else | |
223 m_volumeSlider->want(); | |
224 #endif | |
225 } | |
226 | |
183 updateVolume(); | 227 updateVolume(); |
184 | 228 |
185 refreshClosedCaptionsButtonVisibility(); | 229 refreshClosedCaptionsButtonVisibility(); |
186 | 230 |
187 // Unconditionally allow the user to exit fullscreen if we are in it | 231 // Unconditionally allow the user to exit fullscreen if we are in it |
188 // now. Especially on android, when we might not yet know if | 232 // now. Especially on android, when we might not yet know if |
189 // fullscreen is supported, we sometimes guess incorrectly and show | 233 // fullscreen is supported, we sometimes guess incorrectly and show |
190 // the button earlier, and we don't want to remove it here if the | 234 // the button earlier, and we don't want to remove it here if the |
191 // user chose to enter fullscreen. crbug.com/500732 . | 235 // user chose to enter fullscreen. crbug.com/500732 . |
192 if ((mediaElement().hasVideo() && fullscreenIsSupported(document())) | 236 if ((mediaElement().hasVideo() && fullscreenIsSupported(document())) |
193 || mediaElement().isFullscreen()) | 237 || mediaElement().isFullscreen()) { |
194 m_fullScreenButton->show(); | 238 m_fullScreenButton->want(); |
195 else | 239 } else { |
196 m_fullScreenButton->hide(); | 240 m_fullScreenButton->dontWant(); |
241 } | |
197 | 242 |
198 refreshCastButtonVisibility(); | 243 refreshCastButtonVisibility(); |
244 scheduleUpdateControlsVisibilityForSpace(); | |
fs
2015/07/08 09:31:00
First refreshCastButtonVisibility will call update
liberato (no reviews please)
2015/07/09 12:10:56
updated to ...WithoutLayout(), which is now called
| |
199 makeOpaque(); | 245 makeOpaque(); |
246 | |
247 // Request resize events from our layout object. Our show / hide logic | |
248 // would be better suited to a layout, but JS doesn't have that option. | |
249 // So, we opt for an event-based solution to keep the logic JS-friendly, | |
250 // though the particular event may change. | |
251 if (layoutObject() && useNewUi) | |
252 layoutObject()->setSendResizeEvent(true); | |
200 } | 253 } |
201 | 254 |
202 LayoutObject* MediaControls::layoutObjectForTextTrackLayout() | 255 LayoutObject* MediaControls::layoutObjectForTextTrackLayout() |
203 { | 256 { |
204 return m_panel->layoutObject(); | 257 return m_panel->layoutObject(); |
205 } | 258 } |
206 | 259 |
207 void MediaControls::show() | 260 void MediaControls::show() |
208 { | 261 { |
209 makeOpaque(); | 262 makeOpaque(); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
256 // controls/shadow tree. (Perform the checks separately to avoid going | 309 // controls/shadow tree. (Perform the checks separately to avoid going |
257 // through all the potential ancestor hosts for the focused element.) | 310 // through all the potential ancestor hosts for the focused element.) |
258 const bool ignoreFocus = behaviorFlags & IgnoreFocus; | 311 const bool ignoreFocus = behaviorFlags & IgnoreFocus; |
259 if (!ignoreFocus && (mediaElement().focused() || contains(document().focused Element()))) | 312 if (!ignoreFocus && (mediaElement().focused() || contains(document().focused Element()))) |
260 return false; | 313 return false; |
261 return true; | 314 return true; |
262 } | 315 } |
263 | 316 |
264 void MediaControls::playbackStarted() | 317 void MediaControls::playbackStarted() |
265 { | 318 { |
266 m_currentTimeDisplay->show(); | 319 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) { |
267 m_durationDisplay->hide(); | 320 m_currentTimeDisplay->want(); |
321 m_durationDisplay->dontWant(); | |
322 } | |
268 | 323 |
269 updatePlayState(); | 324 updatePlayState(); |
270 m_timeline->setPosition(mediaElement().currentTime()); | 325 m_timeline->setPosition(mediaElement().currentTime()); |
271 updateCurrentTimeDisplay(); | 326 updateCurrentTimeDisplay(); |
272 | 327 |
273 startHideMediaControlsTimer(); | 328 startHideMediaControlsTimer(); |
274 } | 329 } |
275 | 330 |
276 void MediaControls::playbackProgressed() | 331 void MediaControls::playbackProgressed() |
277 { | 332 { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
318 mediaElement().togglePlayState(); | 373 mediaElement().togglePlayState(); |
319 } | 374 } |
320 } | 375 } |
321 | 376 |
322 void MediaControls::updateCurrentTimeDisplay() | 377 void MediaControls::updateCurrentTimeDisplay() |
323 { | 378 { |
324 double now = mediaElement().currentTime(); | 379 double now = mediaElement().currentTime(); |
325 double duration = mediaElement().duration(); | 380 double duration = mediaElement().duration(); |
326 | 381 |
327 // After seek, hide duration display and show current time. | 382 // After seek, hide duration display and show current time. |
328 if (now > 0) { | 383 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled() && now > 0) { |
329 m_currentTimeDisplay->show(); | 384 m_currentTimeDisplay->want(); |
330 m_durationDisplay->hide(); | 385 m_durationDisplay->dontWant(); |
331 } | 386 } |
332 | 387 |
333 // Allow the theme to format the time. | 388 // Allow the theme to format the time. |
334 m_currentTimeDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsC urrentTime(now, duration), IGNORE_EXCEPTION); | 389 m_currentTimeDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsC urrentTime(now, duration), IGNORE_EXCEPTION); |
335 m_currentTimeDisplay->setCurrentValue(now); | 390 m_currentTimeDisplay->setCurrentValue(now); |
336 } | 391 } |
337 | 392 |
338 void MediaControls::updateVolume() | 393 void MediaControls::updateVolume() |
339 { | 394 { |
340 m_muteButton->updateDisplayType(); | 395 m_muteButton->updateDisplayType(); |
(...skipping 11 matching lines...) Expand all Loading... | |
352 } | 407 } |
353 | 408 |
354 void MediaControls::changedClosedCaptionsVisibility() | 409 void MediaControls::changedClosedCaptionsVisibility() |
355 { | 410 { |
356 m_toggleClosedCaptionsButton->updateDisplayType(); | 411 m_toggleClosedCaptionsButton->updateDisplayType(); |
357 } | 412 } |
358 | 413 |
359 void MediaControls::refreshClosedCaptionsButtonVisibility() | 414 void MediaControls::refreshClosedCaptionsButtonVisibility() |
360 { | 415 { |
361 if (mediaElement().hasClosedCaptions()) | 416 if (mediaElement().hasClosedCaptions()) |
362 m_toggleClosedCaptionsButton->show(); | 417 m_toggleClosedCaptionsButton->want(); |
363 else | 418 else |
364 m_toggleClosedCaptionsButton->hide(); | 419 m_toggleClosedCaptionsButton->dontWant(); |
365 } | 420 } |
366 | 421 |
367 static Element* elementFromCenter(Element& element) | 422 static Element* elementFromCenter(Element& element) |
368 { | 423 { |
369 ClientRect* clientRect = element.getBoundingClientRect(); | 424 ClientRect* clientRect = element.getBoundingClientRect(); |
370 int centerX = static_cast<int>((clientRect->left() + clientRect->right()) / 2); | 425 int centerX = static_cast<int>((clientRect->left() + clientRect->right()) / 2); |
371 int centerY = static_cast<int>((clientRect->top() + clientRect->bottom()) / 2); | 426 int centerY = static_cast<int>((clientRect->top() + clientRect->bottom()) / 2); |
372 | 427 |
373 return element.document().elementFromPoint(centerX , centerY); | 428 return element.document().elementFromPoint(centerX , centerY); |
374 } | 429 } |
375 | 430 |
376 void MediaControls::tryShowOverlayCastButton() | 431 void MediaControls::tryShowOverlayCastButton() |
377 { | 432 { |
378 // The element needs to be shown to have its dimensions and position. | 433 // The element needs to be shown to have its dimensions and position. |
379 m_overlayCastButton->show(); | 434 m_overlayCastButton->show(); |
380 | 435 |
381 if (elementFromCenter(*m_overlayCastButton) != &mediaElement()) | 436 if (elementFromCenter(*m_overlayCastButton) != &mediaElement()) |
382 m_overlayCastButton->hide(); | 437 m_overlayCastButton->hide(); |
383 } | 438 } |
384 | 439 |
385 void MediaControls::refreshCastButtonVisibility() | 440 void MediaControls::refreshCastButtonVisibility() |
386 { | 441 { |
442 refreshCastButtonVisibilityWithoutLayout(); | |
443 updateControlsVisibilityForSpace(); | |
444 } | |
445 | |
446 void MediaControls::refreshCastButtonVisibilityWithoutLayout() | |
philipj_slow
2015/07/08 15:06:38
This name doesn't seem right, getBoundingClientRec
liberato (no reviews please)
2015/07/09 12:10:56
"causes no more layouts than before".
i've rename
| |
447 { | |
387 if (mediaElement().hasRemoteRoutes()) { | 448 if (mediaElement().hasRemoteRoutes()) { |
388 // The reason for the autoplay test is that some pages (e.g. vimeo.com) have an autoplay background video, which | 449 // The reason for the autoplay test is that some pages (e.g. vimeo.com) have an autoplay background video, which |
389 // doesn't autoplay on Chrome for Android (we prevent it) so starts paus ed. In such cases we don't want to automatically | 450 // doesn't autoplay on Chrome for Android (we prevent it) so starts paus ed. In such cases we don't want to automatically |
390 // show the cast button, since it looks strange and is unlikely to corre spond with anything the user wants to do. | 451 // show the cast button, since it looks strange and is unlikely to corre spond with anything the user wants to do. |
391 // If a user does want to cast a paused autoplay video then they can sti ll do so by touching or clicking on the | 452 // If a user does want to cast a paused autoplay video then they can sti ll do so by touching or clicking on the |
392 // video, which will cause the cast button to appear. | 453 // video, which will cause the cast button to appear. |
393 if (!mediaElement().shouldShowControls() && !mediaElement().autoplay() & & mediaElement().paused()) { | 454 if (!mediaElement().shouldShowControls() && !mediaElement().autoplay() & & mediaElement().paused()) { |
455 // Note that this is a case where we add the overlay cast button | |
456 // without wanting the bar cast button. We depend on the fact | |
457 // that scheduleUpdate...() won't change overlay cast button | |
458 // visibility in this case. | |
394 showOverlayCastButton(); | 459 showOverlayCastButton(); |
460 m_castButton->dontWant(); | |
395 } else if (mediaElement().shouldShowControls()) { | 461 } else if (mediaElement().shouldShowControls()) { |
396 m_overlayCastButton->hide(); | 462 m_overlayCastButton->hide(); |
397 m_castButton->show(); | 463 m_castButton->want(); |
398 // Check that the cast button actually fits on the bar. | 464 // Check that the cast button actually fits on the bar. For the |
399 if (m_fullScreenButton->getBoundingClientRect()->right() > m_panel-> getBoundingClientRect()->right()) { | 465 // new ui, we let updateControlsVisibilityForSpace() handle this. |
400 m_castButton->hide(); | 466 if ( !RuntimeEnabledFeatures::newMediaPlaybackUiEnabled() |
467 && m_fullScreenButton->getBoundingClientRect()->right() > m_pane l->getBoundingClientRect()->right()) { | |
468 m_castButton->dontWant(); | |
401 tryShowOverlayCastButton(); | 469 tryShowOverlayCastButton(); |
402 } | 470 } |
403 } | 471 } |
404 } else { | 472 } else { |
405 m_castButton->hide(); | 473 m_castButton->dontWant(); |
406 m_overlayCastButton->hide(); | 474 m_overlayCastButton->hide(); |
407 } | 475 } |
476 | |
477 // do NOT updateControls...() here - that triggers a layout. | |
478 // we could schedule, I suppose, though be careful that it | |
479 // doesn't also trigger one immediately. | |
408 } | 480 } |
409 | 481 |
410 void MediaControls::showOverlayCastButton() | 482 void MediaControls::showOverlayCastButton() |
411 { | 483 { |
412 tryShowOverlayCastButton(); | 484 tryShowOverlayCastButton(); |
413 resetHideMediaControlsTimer(); | 485 resetHideMediaControlsTimer(); |
414 } | 486 } |
415 | 487 |
416 void MediaControls::enteredFullscreen() | 488 void MediaControls::enteredFullscreen() |
417 { | 489 { |
(...skipping 26 matching lines...) Expand all Loading... | |
444 HTMLDivElement::defaultEventHandler(event); | 516 HTMLDivElement::defaultEventHandler(event); |
445 | 517 |
446 // Add IgnoreControlsHover to m_hideTimerBehaviorFlags when we see a touch e vent, | 518 // Add IgnoreControlsHover to m_hideTimerBehaviorFlags when we see a touch e vent, |
447 // to allow the hide-timer to do the right thing when it fires. | 519 // to allow the hide-timer to do the right thing when it fires. |
448 // FIXME: Preferably we would only do this when we're actually handling the event | 520 // FIXME: Preferably we would only do this when we're actually handling the event |
449 // here ourselves. | 521 // here ourselves. |
450 bool wasLastEventTouch = event->isTouchEvent() || event->isGestureEvent() | 522 bool wasLastEventTouch = event->isTouchEvent() || event->isGestureEvent() |
451 || (event->isMouseEvent() && toMouseEvent(event)->fromTouch()); | 523 || (event->isMouseEvent() && toMouseEvent(event)->fromTouch()); |
452 m_hideTimerBehaviorFlags |= wasLastEventTouch ? IgnoreControlsHover : Ignore None; | 524 m_hideTimerBehaviorFlags |= wasLastEventTouch ? IgnoreControlsHover : Ignore None; |
453 | 525 |
526 // If we get a resize event, then update our controls. Note that if | |
527 // we get a resize in the old UI case, update*() will do nothing anyway. | |
528 if (event->type() == EventTypeNames::resize) { | |
529 updateControlsVisibilityForSpace(); | |
530 return; | |
531 } | |
532 | |
454 if (event->type() == EventTypeNames::mouseover) { | 533 if (event->type() == EventTypeNames::mouseover) { |
455 if (!containsRelatedTarget(event)) { | 534 if (!containsRelatedTarget(event)) { |
456 m_isMouseOverControls = true; | 535 m_isMouseOverControls = true; |
457 if (!mediaElement().togglePlayStateWillPlay()) { | 536 if (!mediaElement().togglePlayStateWillPlay()) { |
458 makeOpaque(); | 537 makeOpaque(); |
459 if (shouldHideMediaControls()) | 538 if (shouldHideMediaControls()) |
460 startHideMediaControlsTimer(); | 539 startHideMediaControlsTimer(); |
461 } | 540 } |
462 } | 541 } |
463 return; | 542 return; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
518 bool MediaControls::containsRelatedTarget(Event* event) | 597 bool MediaControls::containsRelatedTarget(Event* event) |
519 { | 598 { |
520 if (!event->isMouseEvent()) | 599 if (!event->isMouseEvent()) |
521 return false; | 600 return false; |
522 EventTarget* relatedTarget = toMouseEvent(event)->relatedTarget(); | 601 EventTarget* relatedTarget = toMouseEvent(event)->relatedTarget(); |
523 if (!relatedTarget) | 602 if (!relatedTarget) |
524 return false; | 603 return false; |
525 return contains(relatedTarget->toNode()); | 604 return contains(relatedTarget->toNode()); |
526 } | 605 } |
527 | 606 |
607 void MediaControls::scheduleUpdateControlsVisibilityForSpace() | |
608 { | |
609 // Schedule an update event for us, of the same type that our LayoutObject | |
610 // will send on resize. We post these rather than directly modify | |
611 // controls visibility because repaints are missed otherwise. | |
612 RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::resize); | |
613 event->setTarget(this); | |
614 LocalDOMWindow* win = document().executingWindow(); | |
615 if (win) | |
616 win->eventQueue()->enqueueEvent(event); | |
617 | |
618 // This causes a relayout when controls are queried, but it also sometimes | |
619 // misses paints. As in, mouse over will cause a control to show / hide. | |
620 updateControlsVisibilityForSpace(); // So that queries work | |
fs
2015/07/08 09:31:00
Having a schedule<operation> that also performs <o
liberato (no reviews please)
2015/07/09 12:10:56
true. it no longer does this.
| |
621 } | |
622 | |
623 void MediaControls::updateControlsVisibilityForSpace() | |
624 { | |
625 // Hide all controls that don't fit, and show the ones that do. | |
626 // This might be better suited for a layout, but since JS media controls | |
627 // won't benefit from that anwyay, we just do it here like JS will. | |
628 // The order, in order of decreasing droppiness: | |
629 // Volume, time, seek bar, cast. | |
630 | |
631 int panelWidth = m_panel->clientWidth(); | |
632 if (panelWidth == 0) | |
633 return; | |
634 | |
635 // Controls that we'll hide / show, in order of decreasing priority. | |
636 MediaControlElement* elements[] = { | |
637 m_playButton.get(), | |
638 m_toggleClosedCaptionsButton.get(), | |
639 m_fullScreenButton.get(), | |
640 m_timeline.get(), | |
641 m_currentTimeDisplay.get(), | |
642 m_volumeSlider.get(), | |
643 m_castButton.get(), | |
644 m_muteButton.get(), | |
645 m_durationDisplay.get(), | |
646 0 | |
647 }; | |
648 | |
649 int usedWidth = 0; | |
650 for (int i = 0; elements[i]; i++) { | |
651 if (elements[i]->isWanted()) { | |
652 if (usedWidth + elements[i]->minimumWidth() <= panelWidth) { | |
653 elements[i]->show(); | |
654 usedWidth += elements[i]->minimumWidth(); | |
655 } else { | |
656 elements[i]->hide(); | |
657 } | |
658 } else { | |
659 elements[i]->hide(); // paranoia. | |
660 } | |
661 } | |
662 | |
663 // Special case for cast: if we want a cast button but dropped it, then | |
664 // show the overlay cast button instead. | |
665 if (m_castButton->isWanted()) { | |
666 if (!m_castButton->isShown()) | |
667 m_overlayCastButton->show(); | |
668 else | |
669 m_overlayCastButton->hide(); | |
670 } // else do not change overlay cast button state. | |
671 } | |
672 | |
528 DEFINE_TRACE(MediaControls) | 673 DEFINE_TRACE(MediaControls) |
529 { | 674 { |
530 visitor->trace(m_mediaElement); | 675 visitor->trace(m_mediaElement); |
531 visitor->trace(m_panel); | 676 visitor->trace(m_panel); |
532 visitor->trace(m_overlayPlayButton); | 677 visitor->trace(m_overlayPlayButton); |
533 visitor->trace(m_overlayEnclosure); | 678 visitor->trace(m_overlayEnclosure); |
534 visitor->trace(m_playButton); | 679 visitor->trace(m_playButton); |
535 visitor->trace(m_currentTimeDisplay); | 680 visitor->trace(m_currentTimeDisplay); |
536 visitor->trace(m_timeline); | 681 visitor->trace(m_timeline); |
537 visitor->trace(m_muteButton); | 682 visitor->trace(m_muteButton); |
538 visitor->trace(m_volumeSlider); | 683 visitor->trace(m_volumeSlider); |
539 visitor->trace(m_toggleClosedCaptionsButton); | 684 visitor->trace(m_toggleClosedCaptionsButton); |
540 visitor->trace(m_fullScreenButton); | 685 visitor->trace(m_fullScreenButton); |
541 visitor->trace(m_durationDisplay); | 686 visitor->trace(m_durationDisplay); |
542 visitor->trace(m_enclosure); | 687 visitor->trace(m_enclosure); |
543 visitor->trace(m_castButton); | 688 visitor->trace(m_castButton); |
544 visitor->trace(m_overlayCastButton); | 689 visitor->trace(m_overlayCastButton); |
545 HTMLDivElement::trace(visitor); | 690 HTMLDivElement::trace(visitor); |
546 } | 691 } |
547 | 692 |
548 } | 693 } |
OLD | NEW |