Chromium Code Reviews| 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 |