forked from mirrors/gecko-dev
Bug 1772339 - Hover states for PiP playback controls r=kpatenio,niklas,flod
Differential Revision: https://phabricator.services.mozilla.com/D149039
This commit is contained in:
parent
eb5e86a54a
commit
01898b809d
5 changed files with 200 additions and 15 deletions
|
|
@ -5,6 +5,9 @@
|
||||||
const { PictureInPicture } = ChromeUtils.import(
|
const { PictureInPicture } = ChromeUtils.import(
|
||||||
"resource://gre/modules/PictureInPicture.jsm"
|
"resource://gre/modules/PictureInPicture.jsm"
|
||||||
);
|
);
|
||||||
|
const { ShortcutUtils } = ChromeUtils.import(
|
||||||
|
"resource://gre/modules/ShortcutUtils.jsm"
|
||||||
|
);
|
||||||
const { DeferredTask } = ChromeUtils.import(
|
const { DeferredTask } = ChromeUtils.import(
|
||||||
"resource://gre/modules/DeferredTask.jsm"
|
"resource://gre/modules/DeferredTask.jsm"
|
||||||
);
|
);
|
||||||
|
|
@ -156,6 +159,12 @@ let Player = {
|
||||||
let playPauseBtn = document.getElementById("playpause");
|
let playPauseBtn = document.getElementById("playpause");
|
||||||
playPauseBtn.focus({ focusVisible: false });
|
playPauseBtn.focus({ focusVisible: false });
|
||||||
|
|
||||||
|
let closeButton = document.getElementById("close");
|
||||||
|
let closeShortcut = document.getElementById("closeShortcut");
|
||||||
|
document.l10n.setAttributes(closeButton, "pictureinpicture-close-cmd", {
|
||||||
|
shortcut: ShortcutUtils.prettifyShortcut(closeShortcut),
|
||||||
|
});
|
||||||
|
|
||||||
// Set the specific remoteType and browsingContextGroupID to use for the
|
// Set the specific remoteType and browsingContextGroupID to use for the
|
||||||
// initial about:blank load. The combination of these two properties will
|
// initial about:blank load. The combination of these two properties will
|
||||||
// ensure that the browser loads in the same process as our originating
|
// ensure that the browser loads in the same process as our originating
|
||||||
|
|
@ -790,7 +799,9 @@ let Player = {
|
||||||
this._isPlaying = isPlaying;
|
this._isPlaying = isPlaying;
|
||||||
this.controls.classList.toggle("playing", isPlaying);
|
this.controls.classList.toggle("playing", isPlaying);
|
||||||
const playButton = document.getElementById("playpause");
|
const playButton = document.getElementById("playpause");
|
||||||
let strId = "pictureinpicture-" + (isPlaying ? "pause" : "play");
|
let strId = isPlaying
|
||||||
|
? `pictureinpicture-pause-cmd`
|
||||||
|
: `pictureinpicture-play-cmd`;
|
||||||
document.l10n.setAttributes(playButton, strId);
|
document.l10n.setAttributes(playButton, strId);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -811,8 +822,14 @@ let Player = {
|
||||||
this._isMuted = isMuted;
|
this._isMuted = isMuted;
|
||||||
this.controls.classList.toggle("muted", isMuted);
|
this.controls.classList.toggle("muted", isMuted);
|
||||||
const audioButton = document.getElementById("audio");
|
const audioButton = document.getElementById("audio");
|
||||||
let strId = "pictureinpicture-" + (isMuted ? "unmute" : "mute");
|
let strId = isMuted
|
||||||
document.l10n.setAttributes(audioButton, strId);
|
? `pictureinpicture-unmute-cmd`
|
||||||
|
: `pictureinpicture-mute-cmd`;
|
||||||
|
let shortcutId = isMuted ? "unMuteShortcut" : "muteShortcut";
|
||||||
|
let shortcut = document.getElementById(shortcutId);
|
||||||
|
document.l10n.setAttributes(audioButton, strId, {
|
||||||
|
shortcut: ShortcutUtils.prettifyShortcut(shortcut),
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@
|
||||||
</xul:commandset>
|
</xul:commandset>
|
||||||
|
|
||||||
<xul:keyset>
|
<xul:keyset>
|
||||||
|
<xul:key id="closeShortcut" key="W" modifiers="accel"/>
|
||||||
|
<xul:key id="muteShortcut" key="↓" modifiers="accel"/>
|
||||||
|
<xul:key id="unMuteShortcut" key="↑" modifiers="accel"/>
|
||||||
#ifndef XP_MACOSX
|
#ifndef XP_MACOSX
|
||||||
<xul:key data-l10n-id="picture-in-picture-toggle-shortcut" command="View:PictureInPicture" modifiers="accel,shift"/>
|
<xul:key data-l10n-id="picture-in-picture-toggle-shortcut" command="View:PictureInPicture" modifiers="accel,shift"/>
|
||||||
<xul:key data-l10n-id="picture-in-picture-toggle-shortcut-alt" command="View:PictureInPicture" modifiers="accel,shift"/>
|
<xul:key data-l10n-id="picture-in-picture-toggle-shortcut-alt" command="View:PictureInPicture" modifiers="accel,shift"/>
|
||||||
|
|
@ -42,18 +45,16 @@
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
mac="true"
|
mac="true"
|
||||||
#endif
|
#endif
|
||||||
data-l10n-id="pictureinpicture-close"
|
|
||||||
tabindex="3"/>
|
tabindex="3"/>
|
||||||
<div id="controls-bottom">
|
<div id="controls-bottom">
|
||||||
<button id="unpip" class="control-item" data-l10n-id="pictureinpicture-unpip" tabindex="2"></button>
|
<button id="unpip" class="control-item" data-l10n-id="pictureinpicture-unpip-cmd" tabindex="2"></button>
|
||||||
<div class="gap"></div>
|
<div class="gap"></div>
|
||||||
<button id="playpause" class="control-item" tabindex="1"
|
<button id="playpause" class="control-item" tabindex="1"
|
||||||
data-l10n-id="pictureinpicture-pause"/>
|
data-l10n-id="pictureinpicture-pause-cmd"/>
|
||||||
<div class="gap" hidden="true"></div>
|
<div class="gap" hidden="true"></div>
|
||||||
<button id="audio" class="control-item" hidden="true" tabindex="1"
|
<button id="audio" class="control-item" hidden="true" tabindex="1"/>
|
||||||
data-l10n-id="pictureinpicture-mute"/>
|
|
||||||
<div class="gap subtitles" hidden="true"></div>
|
<div class="gap subtitles" hidden="true"></div>
|
||||||
<button id="closed-caption" class="control-item closed-caption subtitles" hidden="true" tabindex="1"></button>
|
<button id="closed-caption" class="control-item closed-caption subtitles" hidden="true" data-l10n-id="pictureinpicture-subtitles-cmd" tabindex="1"></button>
|
||||||
<div id="settings" class="hide">
|
<div id="settings" class="hide">
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ prefs =
|
||||||
[browser_contextMenu.js]
|
[browser_contextMenu.js]
|
||||||
skip-if = os == "linux" && bits == 64 && os_version == "18.04" # Bug 1569205
|
skip-if = os == "linux" && bits == 64 && os_version == "18.04" # Bug 1569205
|
||||||
[browser_conflictingPips.js]
|
[browser_conflictingPips.js]
|
||||||
|
[browser_controlsHover.js]
|
||||||
[browser_cornerSnapping.js]
|
[browser_cornerSnapping.js]
|
||||||
run-if = os == "mac"
|
run-if = os == "mac"
|
||||||
[browser_closePlayer.js]
|
[browser_closePlayer.js]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,151 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests functionality for the hover states of the various controls for the Picture-in-Picture
|
||||||
|
* video window.
|
||||||
|
*/
|
||||||
|
add_task(async () => {
|
||||||
|
let videoID = "with-controls";
|
||||||
|
|
||||||
|
await BrowserTestUtils.withNewTab(
|
||||||
|
{
|
||||||
|
url: TEST_PAGE,
|
||||||
|
gBrowser,
|
||||||
|
},
|
||||||
|
async browser => {
|
||||||
|
let waitForVideoEvent = eventType => {
|
||||||
|
return BrowserTestUtils.waitForContentEvent(browser, eventType, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
await ensureVideosReady(browser);
|
||||||
|
await SpecialPowers.spawn(browser, [videoID], async videoID => {
|
||||||
|
await content.document.getElementById(videoID).play();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Open the video in PiP
|
||||||
|
let pipWin = await triggerPictureInPicture(browser, videoID);
|
||||||
|
ok(pipWin, "Got Picture-in-Picture window.");
|
||||||
|
|
||||||
|
const l10n = new Localization(
|
||||||
|
["toolkit/pictureinpicture/pictureinpicture.ftl"],
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
let [
|
||||||
|
close,
|
||||||
|
play,
|
||||||
|
unmute,
|
||||||
|
unpip,
|
||||||
|
subtitles,
|
||||||
|
pause,
|
||||||
|
mute,
|
||||||
|
] = l10n.formatMessagesSync([
|
||||||
|
{
|
||||||
|
id: "pictureinpicture-close-cmd",
|
||||||
|
args: {
|
||||||
|
shortcut: ShortcutUtils.prettifyShortcut(
|
||||||
|
pipWin.document.getElementById("closeShortcut")
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ id: "pictureinpicture-play-cmd" },
|
||||||
|
{
|
||||||
|
id: "pictureinpicture-unmute-cmd",
|
||||||
|
args: {
|
||||||
|
shortcut: ShortcutUtils.prettifyShortcut(
|
||||||
|
pipWin.document.getElementById("unMuteShortcut")
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ id: "pictureinpicture-unpip-cmd" },
|
||||||
|
{ id: "pictureinpicture-subtitles-cmd" },
|
||||||
|
{ id: "pictureinpicture-pause-cmd" },
|
||||||
|
{
|
||||||
|
id: "pictureinpicture-mute-cmd",
|
||||||
|
args: {
|
||||||
|
shortcut: ShortcutUtils.prettifyShortcut(
|
||||||
|
pipWin.document.getElementById("muteShortcut")
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
let closeButton = pipWin.document.getElementById("close");
|
||||||
|
let playPauseButton = pipWin.document.getElementById("playpause");
|
||||||
|
let unpipButton = pipWin.document.getElementById("unpip");
|
||||||
|
let muteUnmuteButton = pipWin.document.getElementById("audio");
|
||||||
|
let subtitlesButton = pipWin.document.getElementById("closed-caption");
|
||||||
|
|
||||||
|
// checks hover title for close button
|
||||||
|
await pipWin.document.l10n.translateFragment(closeButton);
|
||||||
|
Assert.equal(
|
||||||
|
close.attributes[1].value,
|
||||||
|
closeButton.title,
|
||||||
|
"The close button title matches Fluent string"
|
||||||
|
);
|
||||||
|
|
||||||
|
// checks hover title for play button
|
||||||
|
await pipWin.document.l10n.translateFragment(playPauseButton);
|
||||||
|
Assert.equal(
|
||||||
|
pause.attributes[1].value,
|
||||||
|
playPauseButton.title,
|
||||||
|
"The play button title matches Fluent string"
|
||||||
|
);
|
||||||
|
|
||||||
|
// checks hover title for unpip button
|
||||||
|
await pipWin.document.l10n.translateFragment(unpipButton);
|
||||||
|
Assert.equal(
|
||||||
|
unpip.attributes[1].value,
|
||||||
|
unpipButton.title,
|
||||||
|
"The unpip button title matches Fluent string"
|
||||||
|
);
|
||||||
|
|
||||||
|
// checks hover title for subtitles button
|
||||||
|
await pipWin.document.l10n.translateFragment(subtitlesButton);
|
||||||
|
Assert.equal(
|
||||||
|
subtitles.attributes[1].value,
|
||||||
|
subtitlesButton.title,
|
||||||
|
"The subtitles button title matches Fluent string"
|
||||||
|
);
|
||||||
|
|
||||||
|
// checks hover title for unmute button
|
||||||
|
await pipWin.document.l10n.translateFragment(muteUnmuteButton);
|
||||||
|
Assert.equal(
|
||||||
|
mute.attributes[1].value,
|
||||||
|
muteUnmuteButton.title,
|
||||||
|
"The Unmute button title matches Fluent string"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Pause the video
|
||||||
|
let pausedPromise = waitForVideoEvent("pause");
|
||||||
|
EventUtils.synthesizeMouseAtCenter(playPauseButton, {}, pipWin);
|
||||||
|
await pausedPromise;
|
||||||
|
ok(await isVideoPaused(browser, videoID), "The video is paused.");
|
||||||
|
|
||||||
|
// checks hover title for pause button
|
||||||
|
await pipWin.document.l10n.translateFragment(playPauseButton);
|
||||||
|
Assert.equal(
|
||||||
|
play.attributes[1].value,
|
||||||
|
playPauseButton.title,
|
||||||
|
"The pause button title matches Fluent string"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Mute the video
|
||||||
|
let mutedPromise = waitForVideoEvent("volumechange");
|
||||||
|
EventUtils.synthesizeMouseAtCenter(muteUnmuteButton, {}, pipWin);
|
||||||
|
await mutedPromise;
|
||||||
|
ok(await isVideoMuted(browser, videoID), "The audio is muted.");
|
||||||
|
|
||||||
|
// checks hover title for mute button
|
||||||
|
await pipWin.document.l10n.translateFragment(muteUnmuteButton);
|
||||||
|
Assert.equal(
|
||||||
|
unmute.attributes[1].value,
|
||||||
|
muteUnmuteButton.title,
|
||||||
|
"The mute button title matches Fluent string"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
@ -4,21 +4,36 @@
|
||||||
|
|
||||||
pictureinpicture-player-title = Picture-in-Picture
|
pictureinpicture-player-title = Picture-in-Picture
|
||||||
|
|
||||||
pictureinpicture-pause =
|
## Variables:
|
||||||
|
## $shortcut (String) - Keyboard shortcut to execute the command.
|
||||||
|
|
||||||
|
pictureinpicture-pause-cmd =
|
||||||
.aria-label = Pause
|
.aria-label = Pause
|
||||||
pictureinpicture-play =
|
.title = Pause (Spacebar)
|
||||||
|
pictureinpicture-play-cmd =
|
||||||
.aria-label = Play
|
.aria-label = Play
|
||||||
|
.title = Play (Spacebar)
|
||||||
|
|
||||||
pictureinpicture-mute =
|
pictureinpicture-mute-cmd =
|
||||||
.aria-label = Mute
|
.aria-label = Mute
|
||||||
pictureinpicture-unmute =
|
.title = Mute ({ $shortcut })
|
||||||
|
pictureinpicture-unmute-cmd =
|
||||||
.aria-label = Unmute
|
.aria-label = Unmute
|
||||||
|
.title = Unmute ({ $shortcut })
|
||||||
|
|
||||||
pictureinpicture-unpip =
|
pictureinpicture-unpip-cmd =
|
||||||
.aria-label = Send back to tab
|
.aria-label = Send back to tab
|
||||||
|
.title = Back to tab
|
||||||
|
|
||||||
pictureinpicture-close =
|
pictureinpicture-close-cmd =
|
||||||
.aria-label = Close
|
.aria-label = Close
|
||||||
|
.title = Close ({ $shortcut })
|
||||||
|
|
||||||
|
pictureinpicture-subtitles-cmd =
|
||||||
|
.aria-label = Subtitles
|
||||||
|
.title = Subtitles
|
||||||
|
|
||||||
|
##
|
||||||
|
|
||||||
pictureinpicture-subtitles-label = Subtitles
|
pictureinpicture-subtitles-label = Subtitles
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue