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

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

Issue 1156993013: New media playback UI. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: minor decrufting. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
3 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 3 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 29 matching lines...) Expand all
40 40
41 // If you change this value, then also update the corresponding value in 41 // If you change this value, then also update the corresponding value in
42 // LayoutTests/media/media-controls.js. 42 // LayoutTests/media/media-controls.js.
43 static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3; 43 static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3;
44 44
45 static bool fullscreenIsSupported(const Document& document) 45 static bool fullscreenIsSupported(const Document& document)
46 { 46 {
47 return !document.settings() || document.settings()->fullscreenSupported(); 47 return !document.settings() || document.settings()->fullscreenSupported();
48 } 48 }
49 49
50 static bool preferHiddenAudioElements(const Document& document)
51 {
52 return !document.settings() || document.settings()->preferHiddenAudioElement s();
53 }
54
50 MediaControls::MediaControls(HTMLMediaElement& mediaElement) 55 MediaControls::MediaControls(HTMLMediaElement& mediaElement)
51 : HTMLDivElement(mediaElement.document()) 56 : HTMLDivElement(mediaElement.document())
52 , m_mediaElement(&mediaElement) 57 , m_mediaElement(&mediaElement)
53 , m_overlayEnclosure(nullptr) 58 , m_overlayEnclosure(nullptr)
54 , m_overlayPlayButton(nullptr) 59 , m_overlayPlayButton(nullptr)
55 , m_overlayCastButton(nullptr) 60 , m_overlayCastButton(nullptr)
56 , m_enclosure(nullptr) 61 , m_enclosure(nullptr)
57 , m_panel(nullptr) 62 , m_panel(nullptr)
58 , m_playButton(nullptr) 63 , m_playButton(nullptr)
59 , m_timeline(nullptr) 64 , m_timeline(nullptr)
60 , m_currentTimeDisplay(nullptr) 65 , m_currentTimeDisplay(nullptr)
61 , m_durationDisplay(nullptr) 66 , m_durationDisplay(nullptr)
62 , m_muteButton(nullptr) 67 , m_muteButton(nullptr)
63 , m_volumeSlider(nullptr) 68 , m_volumeSlider(nullptr)
64 , m_toggleClosedCaptionsButton(nullptr) 69 , m_toggleClosedCaptionsButton(nullptr)
65 , m_castButton(nullptr) 70 , m_castButton(nullptr)
66 , m_fullScreenButton(nullptr) 71 , m_fullScreenButton(nullptr)
67 , m_hideMediaControlsTimer(this, &MediaControls::hideMediaControlsTimerFired ) 72 , m_hideMediaControlsTimer(this, &MediaControls::hideMediaControlsTimerFired )
68 , m_hideTimerBehaviorFlags(IgnoreNone) 73 , m_hideTimerBehaviorFlags(IgnoreNone)
69 , m_isMouseOverControls(false) 74 , m_isMouseOverControls(false)
70 , m_isPausedForScrubbing(false) 75 , m_isPausedForScrubbing(false)
76 , m_panelWidthChangedTimer(this, &MediaControls::panelWidthChangedTimerFired )
77 , m_panelWidth(0)
78 , m_allowHiddenAudioElements(RuntimeEnabledFeatures::newMediaPlaybackUiEnabl ed())
79 , m_keepMuteButton(false)
71 { 80 {
72 } 81 }
73 82
74 PassRefPtrWillBeRawPtr<MediaControls> MediaControls::create(HTMLMediaElement& me diaElement) 83 PassRefPtrWillBeRawPtr<MediaControls> MediaControls::create(HTMLMediaElement& me diaElement)
75 { 84 {
76 RefPtrWillBeRawPtr<MediaControls> controls = adoptRefWillBeNoop(new MediaCon trols(mediaElement)); 85 RefPtrWillBeRawPtr<MediaControls> controls = adoptRefWillBeNoop(new MediaCon trols(mediaElement));
77 controls->setShadowPseudoId(AtomicString("-webkit-media-controls", AtomicStr ing::ConstructFromLiteral)); 86 controls->setShadowPseudoId(AtomicString("-webkit-media-controls", AtomicStr ing::ConstructFromLiteral));
78 controls->initializeControls(); 87 controls->initializeControls();
79 return controls.release(); 88 return controls.release();
80 } 89 }
81 90
82 // The media controls DOM structure looks like: 91 // The media controls DOM structure looks like:
83 // 92 //
84 // MediaControls (-webkit-media-controls) 93 // MediaControls (-webkit-media-controls)
85 // +-MediaControlOverlayEnclosureElement (-webkit-media-controls-o verlay-enclosure) 94 // +-MediaControlOverlayEnclosureElement (-webkit-media-controls-o verlay-enclosure)
86 // | +-MediaControlOverlayPlayButtonElement (-webkit-media-controls-o verlay-play-button) 95 // | +-MediaControlOverlayPlayButtonElement (-webkit-media-controls-o verlay-play-button)
87 // | | {if mediaControlsOverlayPlayButtonEnabled} 96 // | | {if mediaControlsOverlayPlayButtonEnabled}
88 // | \-MediaControlCastButtonElement (-internal-media-controls -overlay-cast-button) 97 // | \-MediaControlCastButtonElement (-internal-media-controls -overlay-cast-button)
89 // \-MediaControlPanelEnclosureElement (-webkit-media-controls-e nclosure) 98 // \-MediaControlPanelEnclosureElement (-webkit-media-controls-e nclosure)
90 // \-MediaControlPanelElement (-webkit-media-controls-p anel) 99 // \-MediaControlPanelElement (-webkit-media-controls-p anel)
91 // +-MediaControlPlayButtonElement (-webkit-media-controls-p lay-button) 100 // +-MediaControlPlayButtonElement (-webkit-media-controls-p lay-button)
101 // | {if !RTE::newMediaPlaybackUi()}
92 // +-MediaControlTimelineElement (-webkit-media-controls-t imeline) 102 // +-MediaControlTimelineElement (-webkit-media-controls-t imeline)
93 // +-MediaControlCurrentTimeDisplayElement (-webkit-media-controls-c urrent-time-display) 103 // +-MediaControlCurrentTimeDisplayElement (-webkit-media-controls-c urrent-time-display)
94 // +-MediaControlTimeRemainingDisplayElement (-webkit-media-controls-t ime-remaining-display) 104 // +-MediaControlTimeRemainingDisplayElement (-webkit-media-controls-t ime-remaining-display)
105 // | {if RTE::newMediaPlaybackUi()}
106 // +-MediaControlTimelineElement (-webkit-media-controls-t imeline)
95 // +-MediaControlMuteButtonElement (-webkit-media-controls-m ute-button) 107 // +-MediaControlMuteButtonElement (-webkit-media-controls-m ute-button)
96 // +-MediaControlVolumeSliderElement (-webkit-media-controls-v olume-slider) 108 // +-MediaControlVolumeSliderElement (-webkit-media-controls-v olume-slider)
97 // +-MediaControlToggleClosedCaptionsButtonElement (-webkit-media-controls-t oggle-closed-captions-button) 109 // +-MediaControlToggleClosedCaptionsButtonElement (-webkit-media-controls-t oggle-closed-captions-button)
98 // +-MediaControlCastButtonElement (-internal-media-controls -cast-button) 110 // +-MediaControlCastButtonElement (-internal-media-controls -cast-button)
99 // \-MediaControlFullscreenButtonElement (-webkit-media-controls-f ullscreen-button) 111 // \-MediaControlFullscreenButtonElement (-webkit-media-controls-f ullscreen-button)
100 void MediaControls::initializeControls() 112 void MediaControls::initializeControls()
101 { 113 {
114 const bool useNewUi = RuntimeEnabledFeatures::newMediaPlaybackUiEnabled();
102 RefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = M ediaControlOverlayEnclosureElement::create(*this); 115 RefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = M ediaControlOverlayEnclosureElement::create(*this);
103 116
104 if (document().settings() && document().settings()->mediaControlsOverlayPlay ButtonEnabled()) { 117 if (document().settings() && document().settings()->mediaControlsOverlayPlay ButtonEnabled()) {
105 RefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> overlayPlayButt on = MediaControlOverlayPlayButtonElement::create(*this); 118 RefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> overlayPlayButt on = MediaControlOverlayPlayButtonElement::create(*this);
106 m_overlayPlayButton = overlayPlayButton.get(); 119 m_overlayPlayButton = overlayPlayButton.get();
107 overlayEnclosure->appendChild(overlayPlayButton.release()); 120 overlayEnclosure->appendChild(overlayPlayButton.release());
108 } 121 }
109 122
110 RefPtrWillBeRawPtr<MediaControlCastButtonElement> overlayCastButton = MediaC ontrolCastButtonElement::create(*this, true); 123 RefPtrWillBeRawPtr<MediaControlCastButtonElement> overlayCastButton = MediaC ontrolCastButtonElement::create(*this, true);
111 m_overlayCastButton = overlayCastButton.get(); 124 m_overlayCastButton = overlayCastButton.get();
112 overlayEnclosure->appendChild(overlayCastButton.release()); 125 overlayEnclosure->appendChild(overlayCastButton.release());
113 126
114 m_overlayEnclosure = overlayEnclosure.get(); 127 m_overlayEnclosure = overlayEnclosure.get();
115 appendChild(overlayEnclosure.release()); 128 appendChild(overlayEnclosure.release());
116 129
117 // Create an enclosing element for the panel so we can visually offset the c ontrols correctly. 130 // Create an enclosing element for the panel so we can visually offset the c ontrols correctly.
118 RefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> enclosure = MediaContr olPanelEnclosureElement::create(*this); 131 RefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> enclosure = MediaContr olPanelEnclosureElement::create(*this);
119 132
120 RefPtrWillBeRawPtr<MediaControlPanelElement> panel = MediaControlPanelElemen t::create(*this); 133 RefPtrWillBeRawPtr<MediaControlPanelElement> panel = MediaControlPanelElemen t::create(*this);
121 134
122 RefPtrWillBeRawPtr<MediaControlPlayButtonElement> playButton = MediaControlP layButtonElement::create(*this); 135 RefPtrWillBeRawPtr<MediaControlPlayButtonElement> playButton = MediaControlP layButtonElement::create(*this);
123 m_playButton = playButton.get(); 136 m_playButton = playButton.get();
124 panel->appendChild(playButton.release()); 137 panel->appendChild(playButton.release());
125 138
126 RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = MediaControlTimel ineElement::create(*this); 139 RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = MediaControlTimel ineElement::create(*this);
127 m_timeline = timeline.get(); 140 m_timeline = timeline.get();
128 panel->appendChild(timeline.release()); 141 // In old UX, timeline is before the time / duration text.
142 if (!useNewUi)
143 panel->appendChild(timeline.release());
144 // else we will attach it later.
129 145
130 RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(*this); 146 RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(*this);
131 m_currentTimeDisplay = currentTimeDisplay.get(); 147 m_currentTimeDisplay = currentTimeDisplay.get();
132 m_currentTimeDisplay->hide(); 148 m_currentTimeDisplay->setIsWanted(useNewUi);
149
philipj_slow 2015/07/21 12:02:21 Revert extra blank line
liberato (no reviews please) 2015/07/27 20:26:08 Done.
133 panel->appendChild(currentTimeDisplay.release()); 150 panel->appendChild(currentTimeDisplay.release());
134 151
135 RefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(*this); 152 RefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(*this);
136 m_durationDisplay = durationDisplay.get(); 153 m_durationDisplay = durationDisplay.get();
137 panel->appendChild(durationDisplay.release()); 154 panel->appendChild(durationDisplay.release());
138 155
156 // Timeline is after the time / duration text if newMediaPlaybackUiEnabled.
157 if (useNewUi)
158 panel->appendChild(timeline.release());
159
139 RefPtrWillBeRawPtr<MediaControlMuteButtonElement> muteButton = MediaControlM uteButtonElement::create(*this); 160 RefPtrWillBeRawPtr<MediaControlMuteButtonElement> muteButton = MediaControlM uteButtonElement::create(*this);
140 m_muteButton = muteButton.get(); 161 m_muteButton = muteButton.get();
141 panel->appendChild(muteButton.release()); 162 panel->appendChild(muteButton.release());
163 if (m_allowHiddenAudioElements && preferHiddenAudioElements(document()))
164 m_muteButton->setIsWanted(false);
142 165
143 RefPtrWillBeRawPtr<MediaControlVolumeSliderElement> slider = MediaControlVol umeSliderElement::create(*this); 166 RefPtrWillBeRawPtr<MediaControlVolumeSliderElement> slider = MediaControlVol umeSliderElement::create(*this);
144 m_volumeSlider = slider.get(); 167 m_volumeSlider = slider.get();
145 panel->appendChild(slider.release()); 168 panel->appendChild(slider.release());
169 if (m_allowHiddenAudioElements && preferHiddenAudioElements(document()))
170 m_volumeSlider->setIsWanted(false);
146 171
147 RefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClos edCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(*this); 172 RefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClos edCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(*this);
148 m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get(); 173 m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
149 panel->appendChild(toggleClosedCaptionsButton.release()); 174 panel->appendChild(toggleClosedCaptionsButton.release());
150 175
151 RefPtrWillBeRawPtr<MediaControlCastButtonElement> castButton = MediaControlC astButtonElement::create(*this, false); 176 RefPtrWillBeRawPtr<MediaControlCastButtonElement> castButton = MediaControlC astButtonElement::create(*this, false);
152 m_castButton = castButton.get(); 177 m_castButton = castButton.get();
153 panel->appendChild(castButton.release()); 178 panel->appendChild(castButton.release());
154 179
155 RefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> fullscreenButton = M ediaControlFullscreenButtonElement::create(*this); 180 RefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> fullscreenButton = M ediaControlFullscreenButtonElement::create(*this);
156 m_fullScreenButton = fullscreenButton.get(); 181 m_fullScreenButton = fullscreenButton.get();
157 panel->appendChild(fullscreenButton.release()); 182 panel->appendChild(fullscreenButton.release());
158 183
159 m_panel = panel.get(); 184 m_panel = panel.get();
160 enclosure->appendChild(panel.release()); 185 enclosure->appendChild(panel.release());
161 186
162 m_enclosure = enclosure.get(); 187 m_enclosure = enclosure.get();
163 appendChild(enclosure.release()); 188 appendChild(enclosure.release());
164 } 189 }
165 190
166 void MediaControls::reset() 191 void MediaControls::reset()
167 { 192 {
168 double duration = mediaElement().duration(); 193 const bool useNewUi = RuntimeEnabledFeatures::newMediaPlaybackUiEnabled();
194 const double duration = mediaElement().duration();
169 m_durationDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsTime (duration), ASSERT_NO_EXCEPTION); 195 m_durationDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsTime (duration), ASSERT_NO_EXCEPTION);
170 m_durationDisplay->setCurrentValue(duration); 196 m_durationDisplay->setCurrentValue(duration);
171 197
198 if (useNewUi) {
199 // Show everything that we might hide.
200 // If we don't have a duration, then mark it to be hidden. For the
201 // old UI case, want / don't want is the same as show / hide since
202 // it is never marked as not fitting.
203 if (std::isfinite(duration))
204 m_durationDisplay->setIsWanted(true);
philipj_slow 2015/07/21 12:02:21 Can fold this into a single setIsWanted call.
liberato (no reviews please) 2015/07/27 20:26:08 done. don't know why this wasn't one line to begi
205 else
206 m_durationDisplay->setIsWanted(false);
207 m_currentTimeDisplay->setIsWanted(true);
208 m_timeline->setIsWanted(true);
209 }
210
172 updatePlayState(); 211 updatePlayState();
173 212
174 updateCurrentTimeDisplay(); 213 updateCurrentTimeDisplay();
175 214
176 m_timeline->setDuration(duration); 215 m_timeline->setDuration(duration);
177 m_timeline->setPosition(mediaElement().currentTime()); 216 m_timeline->setPosition(mediaElement().currentTime());
178 217
179 if (!mediaElement().hasAudio())
180 m_volumeSlider->hide();
181 else
182 m_volumeSlider->show();
183 updateVolume(); 218 updateVolume();
184 219
185 refreshClosedCaptionsButtonVisibility(); 220 refreshClosedCaptionsButtonVisibility();
186 221
187 // Unconditionally allow the user to exit fullscreen if we are in it 222 // Unconditionally allow the user to exit fullscreen if we are in it
188 // now. Especially on android, when we might not yet know if 223 // now. Especially on android, when we might not yet know if
189 // fullscreen is supported, we sometimes guess incorrectly and show 224 // fullscreen is supported, we sometimes guess incorrectly and show
190 // the button earlier, and we don't want to remove it here if the 225 // the button earlier, and we don't want to remove it here if the
191 // user chose to enter fullscreen. crbug.com/500732 . 226 // user chose to enter fullscreen. crbug.com/500732 .
192 if ((mediaElement().hasVideo() && fullscreenIsSupported(document())) 227 m_fullScreenButton->setIsWanted((mediaElement().hasVideo()
193 || mediaElement().isFullscreen()) 228 && fullscreenIsSupported(document()))
194 m_fullScreenButton->show(); 229 || mediaElement().isFullscreen());
195 else
196 m_fullScreenButton->hide();
197 230
198 refreshCastButtonVisibility(); 231 refreshCastButtonVisibilityWithoutUpdate();
199 makeOpaque(); 232 makeOpaque();
233 changedControlSelections();
200 } 234 }
201 235
202 LayoutObject* MediaControls::layoutObjectForTextTrackLayout() 236 LayoutObject* MediaControls::layoutObjectForTextTrackLayout()
203 { 237 {
204 return m_panel->layoutObject(); 238 return m_panel->layoutObject();
205 } 239 }
206 240
207 void MediaControls::show() 241 void MediaControls::show()
208 { 242 {
209 makeOpaque(); 243 makeOpaque();
210 m_panel->show(); 244 m_panel->setIsWanted(true);
211 m_panel->setIsDisplayed(true); 245 m_panel->setIsDisplayed(true);
212 if (m_overlayPlayButton) 246 if (m_overlayPlayButton)
213 m_overlayPlayButton->updateDisplayType(); 247 m_overlayPlayButton->updateDisplayType();
214 } 248 }
215 249
216 void MediaControls::mediaElementFocused() 250 void MediaControls::mediaElementFocused()
217 { 251 {
218 if (mediaElement().shouldShowControls()) { 252 if (mediaElement().shouldShowControls()) {
219 show(); 253 show();
220 resetHideMediaControlsTimer(); 254 resetHideMediaControlsTimer();
221 } 255 }
222 } 256 }
223 257
224 void MediaControls::hide() 258 void MediaControls::hide()
225 { 259 {
226 m_panel->hide(); 260 m_panel->setIsWanted(false);
227 m_panel->setIsDisplayed(false); 261 m_panel->setIsDisplayed(false);
228 if (m_overlayPlayButton) 262 if (m_overlayPlayButton)
229 m_overlayPlayButton->hide(); 263 m_overlayPlayButton->setIsWanted(false);
230 } 264 }
231 265
232 void MediaControls::makeOpaque() 266 void MediaControls::makeOpaque()
233 { 267 {
234 m_panel->makeOpaque(); 268 m_panel->makeOpaque();
235 } 269 }
236 270
237 void MediaControls::makeTransparent() 271 void MediaControls::makeTransparent()
238 { 272 {
239 m_panel->makeTransparent(); 273 m_panel->makeTransparent();
274 m_overlayCastButton->setIsWanted(false);
240 } 275 }
241 276
242 bool MediaControls::shouldHideMediaControls(unsigned behaviorFlags) const 277 bool MediaControls::shouldHideMediaControls(unsigned behaviorFlags) const
243 { 278 {
244 // Never hide for a media element without visual representation. 279 // Never hide for a media element without visual representation.
245 if (!mediaElement().hasVideo() || mediaElement().isPlayingRemotely()) 280 if (!mediaElement().hasVideo() || mediaElement().isPlayingRemotely())
246 return false; 281 return false;
247 // Don't hide if the mouse is over the controls. 282 // Don't hide if the mouse is over the controls.
248 const bool ignoreControlsHover = behaviorFlags & IgnoreControlsHover; 283 const bool ignoreControlsHover = behaviorFlags & IgnoreControlsHover;
249 if (!ignoreControlsHover && m_panel->hovered()) 284 if (!ignoreControlsHover && m_panel->hovered())
250 return false; 285 return false;
251 // Don't hide if the mouse is over the video area. 286 // Don't hide if the mouse is over the video area.
252 const bool ignoreVideoHover = behaviorFlags & IgnoreVideoHover; 287 const bool ignoreVideoHover = behaviorFlags & IgnoreVideoHover;
253 if (!ignoreVideoHover && m_isMouseOverControls) 288 if (!ignoreVideoHover && m_isMouseOverControls)
254 return false; 289 return false;
255 // Don't hide if focus is on the HTMLMediaElement or within the 290 // Don't hide if focus is on the HTMLMediaElement or within the
256 // controls/shadow tree. (Perform the checks separately to avoid going 291 // controls/shadow tree. (Perform the checks separately to avoid going
257 // through all the potential ancestor hosts for the focused element.) 292 // through all the potential ancestor hosts for the focused element.)
258 const bool ignoreFocus = behaviorFlags & IgnoreFocus; 293 const bool ignoreFocus = behaviorFlags & IgnoreFocus;
259 if (!ignoreFocus && (mediaElement().focused() || contains(document().focused Element()))) 294 if (!ignoreFocus && (mediaElement().focused() || contains(document().focused Element())))
260 return false; 295 return false;
261 return true; 296 return true;
262 } 297 }
263 298
264 void MediaControls::playbackStarted() 299 void MediaControls::playbackStarted()
265 { 300 {
266 m_currentTimeDisplay->show(); 301 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) {
267 m_durationDisplay->hide(); 302 m_currentTimeDisplay->setIsWanted(true);
303 m_durationDisplay->setIsWanted(false);
304 }
268 305
269 updatePlayState(); 306 updatePlayState();
270 m_timeline->setPosition(mediaElement().currentTime()); 307 m_timeline->setPosition(mediaElement().currentTime());
271 updateCurrentTimeDisplay(); 308 updateCurrentTimeDisplay();
272 309
273 startHideMediaControlsTimer(); 310 startHideMediaControlsTimer();
274 } 311 }
275 312
276 void MediaControls::playbackProgressed() 313 void MediaControls::playbackProgressed()
277 { 314 {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 mediaElement().togglePlayState(); 355 mediaElement().togglePlayState();
319 } 356 }
320 } 357 }
321 358
322 void MediaControls::updateCurrentTimeDisplay() 359 void MediaControls::updateCurrentTimeDisplay()
323 { 360 {
324 double now = mediaElement().currentTime(); 361 double now = mediaElement().currentTime();
325 double duration = mediaElement().duration(); 362 double duration = mediaElement().duration();
326 363
327 // After seek, hide duration display and show current time. 364 // After seek, hide duration display and show current time.
328 if (now > 0) { 365 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled() && now > 0) {
329 m_currentTimeDisplay->show(); 366 m_currentTimeDisplay->setIsWanted(true);
330 m_durationDisplay->hide(); 367 m_durationDisplay->setIsWanted(false);
331 } 368 }
332 369
333 // Allow the theme to format the time. 370 // Allow the theme to format the time.
334 m_currentTimeDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsC urrentTime(now, duration), IGNORE_EXCEPTION); 371 m_currentTimeDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsC urrentTime(now, duration), IGNORE_EXCEPTION);
335 m_currentTimeDisplay->setCurrentValue(now); 372 m_currentTimeDisplay->setCurrentValue(now);
336 } 373 }
337 374
338 void MediaControls::updateVolume() 375 void MediaControls::updateVolume()
339 { 376 {
340 m_muteButton->updateDisplayType(); 377 m_muteButton->updateDisplayType();
341 // Invalidate the mute button because it paints differently according to vol ume. 378 // Invalidate the mute button because it paints differently according to vol ume.
342 if (LayoutObject* layoutObject = m_muteButton->layoutObject()) 379 if (LayoutObject* layoutObject = m_muteButton->layoutObject())
343 layoutObject->setShouldDoFullPaintInvalidation(); 380 layoutObject->setShouldDoFullPaintInvalidation();
344 381
345 if (mediaElement().muted()) 382 if (mediaElement().muted()) {
philipj_slow 2015/07/21 12:02:21 Drop the extra {}, presumably left as part of a no
liberato (no reviews please) 2015/07/27 20:26:08 Done.
346 m_volumeSlider->setVolume(0); 383 m_volumeSlider->setVolume(0);
347 else 384 } else {
348 m_volumeSlider->setVolume(mediaElement().volume()); 385 m_volumeSlider->setVolume(mediaElement().volume());
386 }
387
388 // Update the visibility of our audio elements.
389 // We never want the volume slider if there's no audio.
390 // If there is audio, then we want it unless hiding audio is enabled and
391 // we prefer to hide it.
392 m_volumeSlider->setIsWanted(mediaElement().hasAudio()
393 && !(m_allowHiddenAudioElements && preferHiddenAudioElements(document()) ));
394
395 // The mute button is a little more complicated. If enableNewMediaPlaybackU i
396 // is true, then we choose to hide or show the mute button to save space.
397 // If enableNew* is not set, then we never touch the mute button, and
398 // instead let it up to the CSS.
philipj_slow 2015/07/21 12:02:21 s/let/leave/
liberato (no reviews please) 2015/07/27 20:26:08 Done.
399 // Note that this is why m_allowHiddenAudioElements isn't rolled into prefer ...().
400 if (m_allowHiddenAudioElements) {
401 // If there is no audio track, then hide the mute button. If there
402 // is an audio track, then we always show the mute button unless
403 // we prefer to hide it and the media isn't muted. If it's muted,
404 // then we show it to let the user unmute it. In this case, we don't
405 // want to re-hide the mute button later.
406 m_keepMuteButton |= mediaElement().muted();
407 m_muteButton->setIsWanted(mediaElement().hasAudio()
408 && (!preferHiddenAudioElements(document()) || m_keepMuteButton));
409 }
410
411
349 // Invalidate the volume slider because it paints differently according to v olume. 412 // Invalidate the volume slider because it paints differently according to v olume.
350 if (LayoutObject* layoutObject = m_volumeSlider->layoutObject()) 413 if (LayoutObject* layoutObject = m_volumeSlider->layoutObject())
351 layoutObject->setShouldDoFullPaintInvalidation(); 414 layoutObject->setShouldDoFullPaintInvalidation();
352 } 415 }
353 416
354 void MediaControls::changedClosedCaptionsVisibility() 417 void MediaControls::changedClosedCaptionsVisibility()
355 { 418 {
356 m_toggleClosedCaptionsButton->updateDisplayType(); 419 m_toggleClosedCaptionsButton->updateDisplayType();
357 } 420 }
358 421
359 void MediaControls::refreshClosedCaptionsButtonVisibility() 422 void MediaControls::refreshClosedCaptionsButtonVisibility()
360 { 423 {
361 if (mediaElement().hasClosedCaptions()) 424 m_toggleClosedCaptionsButton->setIsWanted(mediaElement().hasClosedCaptions() );
362 m_toggleClosedCaptionsButton->show();
363 else
364 m_toggleClosedCaptionsButton->hide();
365 } 425 }
366 426
367 static Element* elementFromCenter(Element& element) 427 static Element* elementFromCenter(Element& element)
368 { 428 {
369 ClientRect* clientRect = element.getBoundingClientRect(); 429 ClientRect* clientRect = element.getBoundingClientRect();
370 int centerX = static_cast<int>((clientRect->left() + clientRect->right()) / 2); 430 int centerX = static_cast<int>((clientRect->left() + clientRect->right()) / 2);
371 int centerY = static_cast<int>((clientRect->top() + clientRect->bottom()) / 2); 431 int centerY = static_cast<int>((clientRect->top() + clientRect->bottom()) / 2);
372 432
373 return element.document().elementFromPoint(centerX , centerY); 433 return element.document().elementFromPoint(centerX , centerY);
374 } 434 }
375 435
376 void MediaControls::tryShowOverlayCastButton() 436 void MediaControls::tryShowOverlayCastButton()
377 { 437 {
378 // The element needs to be shown to have its dimensions and position. 438 // The element needs to be shown to have its dimensions and position.
379 m_overlayCastButton->show(); 439 m_overlayCastButton->setIsWanted(true);
380
381 if (elementFromCenter(*m_overlayCastButton) != &mediaElement()) 440 if (elementFromCenter(*m_overlayCastButton) != &mediaElement())
382 m_overlayCastButton->hide(); 441 m_overlayCastButton->setIsWanted(false);
383 } 442 }
384 443
385 void MediaControls::refreshCastButtonVisibility() 444 void MediaControls::refreshCastButtonVisibility()
386 { 445 {
446 refreshCastButtonVisibilityWithoutUpdate();
447 changedControlSelections();
448 }
449
450 void MediaControls::refreshCastButtonVisibilityWithoutUpdate()
451 {
387 if (mediaElement().hasRemoteRoutes()) { 452 if (mediaElement().hasRemoteRoutes()) {
388 // The reason for the autoplay test is that some pages (e.g. vimeo.com) have an autoplay background video, which 453 // 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 454 // 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. 455 // 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 456 // 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. 457 // video, which will cause the cast button to appear.
393 if (!mediaElement().shouldShowControls() && !mediaElement().autoplay() & & mediaElement().paused()) { 458 if (!mediaElement().shouldShowControls() && !mediaElement().autoplay() & & mediaElement().paused()) {
394 showOverlayCastButton(); 459 // Note that this is a case where we add the overlay cast button
460 // without wanting the panel cast button. We depend on the fact
461 // that computeWhichControlsFit() won't change overlay cast button
462 // visibility in the case where the cast button isn't wanted.
463 // We don't call compute...() here, but it will be called as
464 // non-cast changes (e.g., resize) occur. If the panel button
465 // is shown, however, compute...() will take control of the
466 // overlay cast button if it needs to hide it from the panel.
467 tryShowOverlayCastButton();
468 m_castButton->setIsWanted(false);
395 } else if (mediaElement().shouldShowControls()) { 469 } else if (mediaElement().shouldShowControls()) {
396 m_overlayCastButton->hide(); 470 m_overlayCastButton->setIsWanted(false);
397 m_castButton->show(); 471 m_castButton->setIsWanted(true);
398 // Check that the cast button actually fits on the bar. 472 // Check that the cast button actually fits on the bar. For the
399 if (m_fullScreenButton->getBoundingClientRect()->right() > m_panel-> getBoundingClientRect()->right()) { 473 // newMediaPlaybackUiEnabled case, we let changedControlSelections()
400 m_castButton->hide(); 474 // handle this.
475 if ( !RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()
476 && m_fullScreenButton->getBoundingClientRect()->right() > m_pane l->getBoundingClientRect()->right()) {
477 m_castButton->setIsWanted(false);
401 tryShowOverlayCastButton(); 478 tryShowOverlayCastButton();
402 } 479 }
403 } 480 }
404 } else { 481 } else {
405 m_castButton->hide(); 482 m_castButton->setIsWanted(false);
406 m_overlayCastButton->hide(); 483 m_overlayCastButton->setIsWanted(false);
407 } 484 }
408 } 485 }
409 486
410 void MediaControls::showOverlayCastButton() 487 void MediaControls::showOverlayCastButton()
411 { 488 {
412 tryShowOverlayCastButton(); 489 tryShowOverlayCastButton();
413 resetHideMediaControlsTimer(); 490 resetHideMediaControlsTimer();
414 } 491 }
415 492
416 void MediaControls::enteredFullscreen() 493 void MediaControls::enteredFullscreen()
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 unsigned behaviorFlags = m_hideTimerBehaviorFlags | IgnoreFocus | IgnoreVide oHover; 564 unsigned behaviorFlags = m_hideTimerBehaviorFlags | IgnoreFocus | IgnoreVide oHover;
488 m_hideTimerBehaviorFlags = IgnoreNone; 565 m_hideTimerBehaviorFlags = IgnoreNone;
489 566
490 if (mediaElement().togglePlayStateWillPlay()) 567 if (mediaElement().togglePlayStateWillPlay())
491 return; 568 return;
492 569
493 if (!shouldHideMediaControls(behaviorFlags)) 570 if (!shouldHideMediaControls(behaviorFlags))
494 return; 571 return;
495 572
496 makeTransparent(); 573 makeTransparent();
497 m_overlayCastButton->hide();
498 } 574 }
499 575
500 void MediaControls::startHideMediaControlsTimer() 576 void MediaControls::startHideMediaControlsTimer()
501 { 577 {
502 m_hideMediaControlsTimer.startOneShot(timeWithoutMouseMovementBeforeHidingMe diaControls, FROM_HERE); 578 m_hideMediaControlsTimer.startOneShot(timeWithoutMouseMovementBeforeHidingMe diaControls, FROM_HERE);
503 } 579 }
504 580
505 void MediaControls::stopHideMediaControlsTimer() 581 void MediaControls::stopHideMediaControlsTimer()
506 { 582 {
507 m_hideMediaControlsTimer.stop(); 583 m_hideMediaControlsTimer.stop();
(...skipping 10 matching lines...) Expand all
518 bool MediaControls::containsRelatedTarget(Event* event) 594 bool MediaControls::containsRelatedTarget(Event* event)
519 { 595 {
520 if (!event->isMouseEvent()) 596 if (!event->isMouseEvent())
521 return false; 597 return false;
522 EventTarget* relatedTarget = toMouseEvent(event)->relatedTarget(); 598 EventTarget* relatedTarget = toMouseEvent(event)->relatedTarget();
523 if (!relatedTarget) 599 if (!relatedTarget)
524 return false; 600 return false;
525 return contains(relatedTarget->toNode()); 601 return contains(relatedTarget->toNode());
526 } 602 }
527 603
604 void MediaControls::notifyPanelWidthChanged(int panelWidth)
605 {
606 // Don't bother to do any work if this matches the most recent panel
607 // width, since we're called after layout.
608 // Note that this code permits a bad frame on resize, since it is
609 // run after the relayout / paint happens. It would be great to improve
610 // this, but it would be even greater to move this code entirely to
611 // JS and fix it there.
612 if (panelWidth == 0)
philipj_slow 2015/07/21 12:02:21 Repeat of earlier issue, why not update m_panelWid
liberato (no reviews please) 2015/07/27 20:26:08 this isn't the same. this is the callback that no
philipj_slow 2015/07/28 15:23:49 Oh, OK. In this case, would it break anything if m
liberato (no reviews please) 2015/07/30 05:54:23 sure, i'll set it here unconditionally and let cha
philipj_slow 2015/08/03 13:10:45 Acknowledged.
613 return;
614
615 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled())
616 return;
617
618 m_panelWidth = panelWidth;
619
620 // Adjust for effective zoom.
621 if (!m_panel->layoutObject() || !m_panel->layoutObject()->style())
622 return;
623 m_panelWidth = ceil(m_panelWidth / m_panel->layoutObject()->style()->effecti veZoom());
624
625 m_panelWidthChangedTimer.startOneShot(0, FROM_HERE);
626 }
627
628 void MediaControls::changedControlSelections()
629 {
630 int panelWidth = m_panel->clientWidth();
philipj_slow 2015/07/21 12:02:21 When is this needed, is it not redundant with noti
liberato (no reviews please) 2015/07/27 20:26:08 when visibility changes, one should call changedCo
philipj_slow 2015/07/28 15:23:49 Hmm, so it seems that if this helps avoid a bad fr
liberato (no reviews please) 2015/07/30 05:54:23 i removed this function. the only case where the
philipj_slow 2015/08/03 13:10:45 What was the source of the appendChild() call here
631 // Don't short-circuit update if the panel hasn't changed. The fit state
632 // is a function of the controls we want, so recompute if we can.
633 if (panelWidth == 0)
634 return;
635
636 m_panelWidth = panelWidth;
637 computeWhichControlsFit();
638 }
639
640 void MediaControls::panelWidthChangedTimerFired(Timer<MediaControls>*)
641 {
642 computeWhichControlsFit();
643 }
644
645 void MediaControls::computeWhichControlsFit()
646 {
647 // Hide all controls that don't fit, and show the ones that do.
648 // This might be better suited for a layout, but since JS media controls
649 // won't benefit from that anwyay, we just do it here like JS will.
650 // The order, in order of decreasing droppiness:
651 // Volume, time, seek bar, cast.
652
653 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled())
654 return;
655
656 if (!m_panelWidth)
657 return;
658
659 // Controls that we'll hide / show, in order of decreasing priority.
660 MediaControlElement* elements[] = {
661 m_playButton.get(),
662 m_toggleClosedCaptionsButton.get(),
663 m_fullScreenButton.get(),
664 m_timeline.get(),
665 m_currentTimeDisplay.get(),
666 m_volumeSlider.get(),
667 m_castButton.get(),
668 m_muteButton.get(),
669 m_durationDisplay.get(),
670 };
671
672 int usedWidth = 0;
673 bool droppedCastButton = false;
674 for (MediaControlElement* element : elements) {
675 if (!element)
676 continue;
677
678 const int minimumWidth = element->minimumWidth();
philipj_slow 2015/07/21 12:02:21 Move this inside the branch where it is used.
liberato (no reviews please) 2015/07/27 20:26:08 Done.
679 if (element->isWanted()) {
680 if (usedWidth + minimumWidth <= m_panelWidth) {
681 element->setDoesFit(true);
682 usedWidth += minimumWidth;
683 } else {
684 element->setDoesFit(false);
685 if (element == m_castButton.get())
686 droppedCastButton = true;
687 }
688 }
689 }
690
691 // Special case for cast: if we want a cast button but dropped it, then
692 // show the overlay cast button instead.
693 if (m_castButton->isWanted())
694 m_overlayCastButton->setIsWanted(droppedCastButton);
695 }
696
697 void MediaControls::setAllowHiddenAudioElements(bool allow)
698 {
699 m_allowHiddenAudioElements = allow;
700 // Clear the 'keep muted flag', for tests.
701 m_keepMuteButton = false;
philipj_slow 2015/07/21 12:02:21 Do you also want it to be reset when loading a new
liberato (no reviews please) 2015/07/27 20:26:08 good point, will reset in reset().
philipj_slow 2015/08/03 13:10:45 Acknowledged.
702 // Update the controls visibility.
703 updateVolume();
704 }
705
528 DEFINE_TRACE(MediaControls) 706 DEFINE_TRACE(MediaControls)
529 { 707 {
530 visitor->trace(m_mediaElement); 708 visitor->trace(m_mediaElement);
531 visitor->trace(m_panel); 709 visitor->trace(m_panel);
532 visitor->trace(m_overlayPlayButton); 710 visitor->trace(m_overlayPlayButton);
533 visitor->trace(m_overlayEnclosure); 711 visitor->trace(m_overlayEnclosure);
534 visitor->trace(m_playButton); 712 visitor->trace(m_playButton);
535 visitor->trace(m_currentTimeDisplay); 713 visitor->trace(m_currentTimeDisplay);
536 visitor->trace(m_timeline); 714 visitor->trace(m_timeline);
537 visitor->trace(m_muteButton); 715 visitor->trace(m_muteButton);
538 visitor->trace(m_volumeSlider); 716 visitor->trace(m_volumeSlider);
539 visitor->trace(m_toggleClosedCaptionsButton); 717 visitor->trace(m_toggleClosedCaptionsButton);
540 visitor->trace(m_fullScreenButton); 718 visitor->trace(m_fullScreenButton);
541 visitor->trace(m_durationDisplay); 719 visitor->trace(m_durationDisplay);
542 visitor->trace(m_enclosure); 720 visitor->trace(m_enclosure);
543 visitor->trace(m_castButton); 721 visitor->trace(m_castButton);
544 visitor->trace(m_overlayCastButton); 722 visitor->trace(m_overlayCastButton);
545 HTMLDivElement::trace(visitor); 723 HTMLDivElement::trace(visitor);
546 } 724 }
547 725
548 } 726 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698