Commit f832578e authored by François Beaufort's avatar François Beaufort Committed by Commit Bot

[Media Controls] Add Exit Picture-in-Picture button.

This makes sure clicking the native Picture-in-Picture button (after
entering Picture-in-Picture) exits Picture-in-Picture and that video
controls are reflected when entering and exiting Picture-in-Picture.

Screenshot: https://i.imgur.com/081Xbmb.png

Bug: 840516, 806249
Change-Id: I410a4a06cc4eea62dae8e1d368e4d05394f13c86
Reviewed-on: https://chromium-review.googlesource.com/1084833
Commit-Queue: François Beaufort <beaufort.francois@gmail.com>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Reviewed-by: default avatarJochen Eisinger <jochen@chromium.org>
Reviewed-by: default avatarapacible <apacible@chromium.org>
Cr-Commit-Position: refs/heads/master@{#564807}
parent ef1c7e05
...@@ -660,6 +660,14 @@ below: ...@@ -660,6 +660,14 @@ below:
exit full screen exit full screen
</message> </message>
<message name="IDS_AX_MEDIA_ENTER_PICTURE_IN_PICTURE_BUTTON" desc="Accessibility role description for enter Picture-in-Picture button">
enter picture-in-picture
</message>
<message name="IDS_AX_MEDIA_EXIT_PICTURE_IN_PICTURE_BUTTON" desc="Accessibility role description for exit Picture-in-Picture button">
exit picture-in-picture
</message>
<message name="IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON" desc="Accessibility role description for show closed captions button"> <message name="IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON" desc="Accessibility role description for show closed captions button">
show closed captions show closed captions
</message> </message>
...@@ -732,6 +740,14 @@ below: ...@@ -732,6 +740,14 @@ below:
exit full screen exit full screen
</message> </message>
<message name="IDS_AX_MEDIA_ENTER_PICTURE_IN_PICTURE_BUTTON_HELP" desc="Accessibility help description for enter Picture-in-Picture button">
play video in picture-in-picture mode
</message>
<message name="IDS_AX_MEDIA_EXIT_PICTURE_IN_PICTURE_BUTTON_HELP" desc="Accessibility help description for exit Picture-in-Picture button">
exit picture-in-picture
</message>
<message name="IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON_HELP" desc="Accessibility help description for show closed captions button"> <message name="IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON_HELP" desc="Accessibility help description for show closed captions button">
start displaying closed captions start displaying closed captions
</message> </message>
...@@ -938,9 +954,12 @@ below: ...@@ -938,9 +954,12 @@ below:
<message name="IDS_MEDIA_OVERFLOW_MENU_DOWNLOAD" desc="Media controls overflow menu item label for a download button."> <message name="IDS_MEDIA_OVERFLOW_MENU_DOWNLOAD" desc="Media controls overflow menu item label for a download button.">
Download Download
</message> </message>
<message name="IDS_MEDIA_OVERFLOW_MENU_PICTURE_IN_PICTURE" desc="Media controls overflow menu item label for a picture-in-picture button."> <message name="IDS_MEDIA_OVERFLOW_MENU_ENTER_PICTURE_IN_PICTURE" desc="Media controls overflow menu item label for a button to enter Picture-in-Picture.">
Picture-in-Picture Picture-in-Picture
</message> </message>
<message name="IDS_MEDIA_OVERFLOW_MENU_EXIT_PICTURE_IN_PICTURE" desc="Media controls overflow menu item label for a button to exit Picture-in-Picture.">
Exit Picture-in-Picture
</message>
<message name="IDS_MEDIA_PICTURE_IN_PICTURE_INTERSTITIAL_TEXT" desc="Text message shown to user when in picture in picture mode. When a video is in picture in picture mode, an interstitial with this text appears where the video player is positioned. The video continues to play back in another window that gives the experience that the video is 'popped out'."> <message name="IDS_MEDIA_PICTURE_IN_PICTURE_INTERSTITIAL_TEXT" desc="Text message shown to user when in picture in picture mode. When a video is in picture in picture mode, an interstitial with this text appears where the video player is positioned. The video continues to play back in another window that gives the experience that the video is 'popped out'.">
This video is playing in Picture-in-Picture This video is playing in Picture-in-Picture
</message> </message>
......
...@@ -105,6 +105,10 @@ static int ToMessageID(WebLocalizedString::Name name) { ...@@ -105,6 +105,10 @@ static int ToMessageID(WebLocalizedString::Name name) {
return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON; return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON;
case WebLocalizedString::kAXMediaExitFullscreenButton: case WebLocalizedString::kAXMediaExitFullscreenButton:
return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON; return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON;
case WebLocalizedString::kAXMediaEnterPictureInPictureButton:
return IDS_AX_MEDIA_ENTER_PICTURE_IN_PICTURE_BUTTON;
case WebLocalizedString::kAXMediaExitPictureInPictureButton:
return IDS_AX_MEDIA_EXIT_PICTURE_IN_PICTURE_BUTTON;
case WebLocalizedString::kAXMediaShowClosedCaptionsButton: case WebLocalizedString::kAXMediaShowClosedCaptionsButton:
return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON; return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON;
case WebLocalizedString::kAXMediaHideClosedCaptionsButton: case WebLocalizedString::kAXMediaHideClosedCaptionsButton:
...@@ -141,6 +145,10 @@ static int ToMessageID(WebLocalizedString::Name name) { ...@@ -141,6 +145,10 @@ static int ToMessageID(WebLocalizedString::Name name) {
return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON_HELP; return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON_HELP;
case WebLocalizedString::kAXMediaExitFullscreenButtonHelp: case WebLocalizedString::kAXMediaExitFullscreenButtonHelp:
return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON_HELP; return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON_HELP;
case WebLocalizedString::kAXMediaEnterPictureInPictureButtonHelp:
return IDS_AX_MEDIA_ENTER_PICTURE_IN_PICTURE_BUTTON_HELP;
case WebLocalizedString::kAXMediaExitPictureInPictureButtonHelp:
return IDS_AX_MEDIA_EXIT_PICTURE_IN_PICTURE_BUTTON_HELP;
case WebLocalizedString::kAXMediaShowClosedCaptionsButtonHelp: case WebLocalizedString::kAXMediaShowClosedCaptionsButtonHelp:
return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON_HELP; return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON_HELP;
case WebLocalizedString::kAXMediaHideClosedCaptionsButtonHelp: case WebLocalizedString::kAXMediaHideClosedCaptionsButtonHelp:
...@@ -223,8 +231,10 @@ static int ToMessageID(WebLocalizedString::Name name) { ...@@ -223,8 +231,10 @@ static int ToMessageID(WebLocalizedString::Name name) {
return IDS_MEDIA_OVERFLOW_MENU_PAUSE; return IDS_MEDIA_OVERFLOW_MENU_PAUSE;
case WebLocalizedString::kOverflowMenuDownload: case WebLocalizedString::kOverflowMenuDownload:
return IDS_MEDIA_OVERFLOW_MENU_DOWNLOAD; return IDS_MEDIA_OVERFLOW_MENU_DOWNLOAD;
case WebLocalizedString::kOverflowMenuPictureInPicture: case WebLocalizedString::kOverflowMenuEnterPictureInPicture:
return IDS_MEDIA_OVERFLOW_MENU_PICTURE_IN_PICTURE; return IDS_MEDIA_OVERFLOW_MENU_ENTER_PICTURE_IN_PICTURE;
case WebLocalizedString::kOverflowMenuExitPictureInPicture:
return IDS_MEDIA_OVERFLOW_MENU_EXIT_PICTURE_IN_PICTURE;
case WebLocalizedString::kPictureInPictureInterstitialText: case WebLocalizedString::kPictureInPictureInterstitialText:
return IDS_MEDIA_PICTURE_IN_PICTURE_INTERSTITIAL_TEXT; return IDS_MEDIA_PICTURE_IN_PICTURE_INTERSTITIAL_TEXT;
case WebLocalizedString::kPlaceholderForDayOfMonthField: case WebLocalizedString::kPlaceholderForDayOfMonthField:
......
...@@ -18,6 +18,13 @@ async_test(t => { ...@@ -18,6 +18,13 @@ async_test(t => {
assert_true(isPictureInPictureButtonEnabled(video), "button should exist"); assert_true(isPictureInPictureButtonEnabled(video), "button should exist");
video.addEventListener('enterpictureinpicture', t.step_func(() => { video.addEventListener('enterpictureinpicture', t.step_func(() => {
setTimeout(t.step_func(() => {
assert_true(isPictureInPictureButtonEnabled(video), "button should exist");
clickPictureInPictureButton(video);
}));
}), { once: true });
video.addEventListener('leavepictureinpicture', t.step_func(() => {
setTimeout(t.step_func_done(() => { setTimeout(t.step_func_done(() => {
assert_true(isPictureInPictureButtonEnabled(video), "button should exist"); assert_true(isPictureInPictureButtonEnabled(video), "button should exist");
})); }));
......
...@@ -19,9 +19,17 @@ async_test(t => { ...@@ -19,9 +19,17 @@ async_test(t => {
checkPictureInPictureInterstitialDoesNotExist(video); checkPictureInPictureInterstitialDoesNotExist(video);
video.addEventListener('enterpictureinpicture', t.step_func_done(() => { video.addEventListener('enterpictureinpicture', t.step_func(() => {
assert_true(isPictureInPictureInterstitialVisible(video), assert_true(isPictureInPictureInterstitialVisible(video),
"Interstitial should be visible when video enters Picture-in-Picture"); "Interstitial should be visible when video enters Picture-in-Picture");
clickPictureInPictureButton(video);
}));
video.addEventListener('leavepictureinpicture', t.step_func(() => {
setTimeout(t.step_func_done(() => {
assert_false(isPictureInPictureInterstitialVisible(video),
"Interstitial should not be visible when video leaves Picture-in-Picture");
}), 300 /* transition */);
})); }));
clickPictureInPictureButton(video); clickPictureInPictureButton(video);
......
...@@ -76,6 +76,10 @@ struct WebLocalizedString { ...@@ -76,6 +76,10 @@ struct WebLocalizedString {
kAXMediaVideoElement, kAXMediaVideoElement,
kAXMediaVideoElementHelp, kAXMediaVideoElementHelp,
kAXMediaVideoSliderHelp, kAXMediaVideoSliderHelp,
kAXMediaEnterPictureInPictureButton,
kAXMediaEnterPictureInPictureButtonHelp,
kAXMediaExitPictureInPictureButton,
kAXMediaExitPictureInPictureButtonHelp,
kAXMillisecondFieldText, kAXMillisecondFieldText,
kAXMinuteFieldText, kAXMinuteFieldText,
kAXMonthFieldText, kAXMonthFieldText,
...@@ -113,7 +117,8 @@ struct WebLocalizedString { ...@@ -113,7 +117,8 @@ struct WebLocalizedString {
kOverflowMenuPlay, kOverflowMenuPlay,
kOverflowMenuPause, kOverflowMenuPause,
kOverflowMenuDownload, kOverflowMenuDownload,
kOverflowMenuPictureInPicture, kOverflowMenuEnterPictureInPicture,
kOverflowMenuExitPictureInPicture,
kPictureInPictureInterstitialText, kPictureInPictureInterstitialText,
// kPlaceholderForDayOfMonthField is for day placeholder text, e.g. // kPlaceholderForDayOfMonthField is for day placeholder text, e.g.
// "dd", for date field used in multiple fields "date", "datetime", and // "dd", for date field used in multiple fields "date", "datetime", and
......
...@@ -40,10 +40,14 @@ class CORE_EXPORT PictureInPictureController ...@@ -40,10 +40,14 @@ class CORE_EXPORT PictureInPictureController
kDisabledByAttribute, kDisabledByAttribute,
}; };
// Enter Picture-in-Picture for a video element and resolve promise. // Enter Picture-in-Picture for a video element and resolve promise if any.
virtual void EnterPictureInPicture(HTMLVideoElement*, virtual void EnterPictureInPicture(HTMLVideoElement*,
ScriptPromiseResolver*) = 0; ScriptPromiseResolver*) = 0;
// Exit Picture-in-Picture for a video element and resolve promise if any.
virtual void ExitPictureInPicture(HTMLVideoElement*,
ScriptPromiseResolver*) = 0;
// Returns whether a given video element in a document associated with the // Returns whether a given video element in a document associated with the
// controller is allowed to request Picture-in-Picture. // controller is allowed to request Picture-in-Picture.
virtual Status IsElementAllowed(const HTMLVideoElement&) const = 0; virtual Status IsElementAllowed(const HTMLVideoElement&) const = 0;
......
...@@ -90,6 +90,8 @@ AXObject* AccessibilityMediaControl::Create( ...@@ -90,6 +90,8 @@ AXObject* AccessibilityMediaControl::Create(
case kMediaOverflowList: case kMediaOverflowList:
case kMediaDownloadButton: case kMediaDownloadButton:
case kMediaScrubbingMessage: case kMediaScrubbingMessage:
case kMediaEnterPictureInPictureButton:
case kMediaExitPictureInPictureButton:
return new AccessibilityMediaControl(layout_object, ax_object_cache); return new AccessibilityMediaControl(layout_object, ax_object_cache);
} }
...@@ -171,6 +173,12 @@ String AccessibilityMediaControl::TextAlternative( ...@@ -171,6 +173,12 @@ String AccessibilityMediaControl::TextAlternative(
case kMediaOverflowList: case kMediaOverflowList:
case kMediaScrubbingMessage: case kMediaScrubbingMessage:
return QueryString(WebLocalizedString::kAXMediaDefault); return QueryString(WebLocalizedString::kAXMediaDefault);
case kMediaEnterPictureInPictureButton:
return QueryString(
WebLocalizedString::kAXMediaEnterPictureInPictureButton);
case kMediaExitPictureInPictureButton:
return QueryString(
WebLocalizedString::kAXMediaExitPictureInPictureButton);
case kMediaSlider: case kMediaSlider:
NOTREACHED(); NOTREACHED();
return QueryString(WebLocalizedString::kAXMediaDefault); return QueryString(WebLocalizedString::kAXMediaDefault);
...@@ -215,6 +223,12 @@ String AccessibilityMediaControl::Description( ...@@ -215,6 +223,12 @@ String AccessibilityMediaControl::Description(
return QueryString(WebLocalizedString::kAXMediaCastOnButtonHelp); return QueryString(WebLocalizedString::kAXMediaCastOnButtonHelp);
case kMediaOverflowButton: case kMediaOverflowButton:
return QueryString(WebLocalizedString::kAXMediaOverflowButtonHelp); return QueryString(WebLocalizedString::kAXMediaOverflowButtonHelp);
case kMediaEnterPictureInPictureButton:
return QueryString(
WebLocalizedString::kAXMediaEnterPictureInPictureButtonHelp);
case kMediaExitPictureInPictureButton:
return QueryString(
WebLocalizedString::kAXMediaExitPictureInPictureButtonHelp);
case kMediaSliderThumb: case kMediaSliderThumb:
case kMediaTextTrackList: case kMediaTextTrackList:
case kMediaTimelineContainer: case kMediaTimelineContainer:
...@@ -262,6 +276,8 @@ AccessibilityRole AccessibilityMediaControl::RoleValue() const { ...@@ -262,6 +276,8 @@ AccessibilityRole AccessibilityMediaControl::RoleValue() const {
case kMediaDownloadButton: case kMediaDownloadButton:
case kMediaCastOnButton: case kMediaCastOnButton:
case kMediaCastOffButton: case kMediaCastOffButton:
case kMediaEnterPictureInPictureButton:
case kMediaExitPictureInPictureButton:
return kButtonRole; return kButtonRole;
case kMediaTimelineContainer: case kMediaTimelineContainer:
......
...@@ -36,6 +36,8 @@ enum MediaControlElementType { ...@@ -36,6 +36,8 @@ enum MediaControlElementType {
kMediaOverflowList, kMediaOverflowList,
kMediaDownloadButton, kMediaDownloadButton,
kMediaScrubbingMessage, kMediaScrubbingMessage,
kMediaEnterPictureInPictureButton,
kMediaExitPictureInPictureButton,
}; };
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_ELEMENT_TYPE_H_ #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_ELEMENT_TYPE_H_
...@@ -29,9 +29,29 @@ bool MediaControlPictureInPictureButtonElement:: ...@@ -29,9 +29,29 @@ bool MediaControlPictureInPictureButtonElement::
return true; return true;
} }
void MediaControlPictureInPictureButtonElement::UpdateDisplayType() {
DCHECK(MediaElement().IsHTMLVideoElement());
bool isInPictureInPicture =
PictureInPictureControllerImpl::From(MediaElement().GetDocument())
.IsPictureInPictureElement(&ToHTMLVideoElement(MediaElement()));
SetDisplayType(isInPictureInPicture ? kMediaExitPictureInPictureButton
: kMediaEnterPictureInPictureButton);
SetClass("on", isInPictureInPicture);
UpdateOverflowString();
MediaControlInputElement::UpdateDisplayType();
}
WebLocalizedString::Name WebLocalizedString::Name
MediaControlPictureInPictureButtonElement::GetOverflowStringName() const { MediaControlPictureInPictureButtonElement::GetOverflowStringName() const {
return WebLocalizedString::kOverflowMenuPictureInPicture; DCHECK(MediaElement().IsHTMLVideoElement());
bool isInPictureInPicture =
PictureInPictureControllerImpl::From(MediaElement().GetDocument())
.IsPictureInPictureElement(&ToHTMLVideoElement(MediaElement()));
return isInPictureInPicture
? WebLocalizedString::kOverflowMenuExitPictureInPicture
: WebLocalizedString::kOverflowMenuEnterPictureInPicture;
} }
bool MediaControlPictureInPictureButtonElement::HasOverflowButton() const { bool MediaControlPictureInPictureButtonElement::HasOverflowButton() const {
...@@ -51,9 +71,11 @@ void MediaControlPictureInPictureButtonElement::DefaultEventHandler( ...@@ -51,9 +71,11 @@ void MediaControlPictureInPictureButtonElement::DefaultEventHandler(
PictureInPictureControllerImpl::From(MediaElement().GetDocument()); PictureInPictureControllerImpl::From(MediaElement().GetDocument());
DCHECK(MediaElement().IsHTMLVideoElement()); DCHECK(MediaElement().IsHTMLVideoElement());
// TODO(crbug.com/840516): Toggle PiP instead. HTMLVideoElement* video_element = &ToHTMLVideoElement(MediaElement());
controller.EnterPictureInPicture(&ToHTMLVideoElement(MediaElement()), if (controller.IsPictureInPictureElement(video_element))
nullptr); controller.ExitPictureInPicture(video_element, nullptr);
else
controller.EnterPictureInPicture(video_element, nullptr);
} }
MediaControlInputElement::DefaultEventHandler(event); MediaControlInputElement::DefaultEventHandler(event);
......
...@@ -19,6 +19,7 @@ class MediaControlPictureInPictureButtonElement final ...@@ -19,6 +19,7 @@ class MediaControlPictureInPictureButtonElement final
// MediaControlInputElement: // MediaControlInputElement:
bool WillRespondToMouseClickEvents() override; bool WillRespondToMouseClickEvents() override;
void UpdateDisplayType() override;
WebLocalizedString::Name GetOverflowStringName() const override; WebLocalizedString::Name GetOverflowStringName() const override;
bool HasOverflowButton() const override; bool HasOverflowButton() const override;
......
...@@ -1678,6 +1678,10 @@ void MediaControlsImpl::OnExitedFullscreen() { ...@@ -1678,6 +1678,10 @@ void MediaControlsImpl::OnExitedFullscreen() {
StartHideMediaControlsTimer(); StartHideMediaControlsTimer();
} }
void MediaControlsImpl::OnPictureInPictureChanged() {
picture_in_picture_button_->UpdateDisplayType();
}
void MediaControlsImpl::OnPanelKeypress() { void MediaControlsImpl::OnPanelKeypress() {
// If the user is interacting with the controls via the keyboard, don't hide // If the user is interacting with the controls via the keyboard, don't hide
// the controls. This is called when the user mutes/unmutes, turns CC on/off, // the controls. This is called when the user mutes/unmutes, turns CC on/off,
......
...@@ -315,6 +315,7 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement, ...@@ -315,6 +315,7 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
void OnLoadedMetadata(); void OnLoadedMetadata();
void OnEnteredFullscreen(); void OnEnteredFullscreen();
void OnExitedFullscreen(); void OnExitedFullscreen();
void OnPictureInPictureChanged();
void OnPanelKeypress(); void OnPanelKeypress();
void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(event); } void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(event); }
void OnWaiting(); void OnWaiting();
......
...@@ -49,6 +49,14 @@ void MediaControlsMediaEventListener::Attach() { ...@@ -49,6 +49,14 @@ void MediaControlsMediaEventListener::Attach() {
media_controls_->GetDocument().addEventListener( media_controls_->GetDocument().addEventListener(
EventTypeNames::fullscreenchange, this, false); EventTypeNames::fullscreenchange, this, false);
// Picture-in-Picture events.
if (RuntimeEnabledFeatures::PictureInPictureEnabled()) {
GetMediaElement().addEventListener(EventTypeNames::enterpictureinpicture,
this, false);
GetMediaElement().addEventListener(EventTypeNames::leavepictureinpicture,
this, false);
}
// TextTracks events. // TextTracks events.
TextTrackList* text_tracks = GetMediaElement().textTracks(); TextTrackList* text_tracks = GetMediaElement().textTracks();
text_tracks->addEventListener(EventTypeNames::addtrack, this, false); text_tracks->addEventListener(EventTypeNames::addtrack, this, false);
...@@ -188,6 +196,13 @@ void MediaControlsMediaEventListener::handleEvent( ...@@ -188,6 +196,13 @@ void MediaControlsMediaEventListener::handleEvent(
return; return;
} }
// Picture-in-Picture events.
if (event->type() == EventTypeNames::enterpictureinpicture ||
event->type() == EventTypeNames::leavepictureinpicture) {
media_controls_->OnPictureInPictureChanged();
return;
}
// TextTracks events. // TextTracks events.
if (event->type() == EventTypeNames::addtrack || if (event->type() == EventTypeNames::addtrack ||
event->type() == EventTypeNames::removetrack) { event->type() == EventTypeNames::removetrack) {
......
<svg width="22" height="18" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd" opacity=".87">
<path d="M18 4H4v10h14V4zm4 12V1.98C22 .88 21.1 0 20 0H2C.9 0 0 .88 0 1.98V16c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2zm-2 .02H2V1.97h18v14.05z" fill="#000" fill-rule="nonzero"/>
<path d="M-1-3h24v24H-1z"/>
</g>
</svg>
\ No newline at end of file
...@@ -344,6 +344,11 @@ video::-internal-media-controls-picture-in-picture-button { ...@@ -344,6 +344,11 @@ video::-internal-media-controls-picture-in-picture-button {
url(ic_picture_in_picture.svg) 1x); url(ic_picture_in_picture.svg) 1x);
} }
video::-internal-media-controls-picture-in-picture-button.on {
background-image: -webkit-image-set(
url(ic_picture_in_picture_exit.svg) 1x);
}
video::-webkit-media-controls:not(.audio-only) [pseudo="-webkit-media-controls-panel"] [pseudo="-internal-media-controls-overflow-button"] { video::-webkit-media-controls:not(.audio-only) [pseudo="-webkit-media-controls-panel"] [pseudo="-internal-media-controls-overflow-button"] {
background-image: -webkit-image-set(url(ic_menu_white.svg) 1x); background-image: -webkit-image-set(url(ic_menu_white.svg) 1x);
} }
......
...@@ -49,15 +49,13 @@ class PictureInPictureControllerImpl : public PictureInPictureController { ...@@ -49,15 +49,13 @@ class PictureInPictureControllerImpl : public PictureInPictureController {
ScriptPromiseResolver*, ScriptPromiseResolver*,
const WebSize& picture_in_picture_window_size); const WebSize& picture_in_picture_window_size);
// Exit Picture-in-Picture for a video element and resolve promise if any.
void ExitPictureInPicture(HTMLVideoElement*, ScriptPromiseResolver*);
// Returns element currently in Picture-in-Picture if any. Null otherwise. // Returns element currently in Picture-in-Picture if any. Null otherwise.
Element* PictureInPictureElement(TreeScope&) const; Element* PictureInPictureElement(TreeScope&) const;
// Implementation of PictureInPictureController. // Implementation of PictureInPictureController.
void EnterPictureInPicture(HTMLVideoElement*, void EnterPictureInPicture(HTMLVideoElement*,
ScriptPromiseResolver*) override; ScriptPromiseResolver*) override;
void ExitPictureInPicture(HTMLVideoElement*, ScriptPromiseResolver*) override;
void OnExitedPictureInPicture(ScriptPromiseResolver*) override; void OnExitedPictureInPicture(ScriptPromiseResolver*) override;
Status IsElementAllowed(const HTMLVideoElement&) const override; Status IsElementAllowed(const HTMLVideoElement&) const override;
bool IsPictureInPictureElement(const Element*) const override; bool IsPictureInPictureElement(const Element*) const override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment