зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 951a331c6511 (bug 1748884) for causing failures on browser_text_tracks_webvtt_2.js. CLOSED TREE
This commit is contained in:
Родитель
0109816695
Коммит
5139fa51ef
|
@ -409,7 +409,6 @@ pref("media.decoder-doctor.verbose", false);
|
||||||
pref("media.decoder-doctor.new-issue-endpoint", "https://webcompat.com/issues/new");
|
pref("media.decoder-doctor.new-issue-endpoint", "https://webcompat.com/issues/new");
|
||||||
|
|
||||||
pref("media.videocontrols.picture-in-picture.enabled", false);
|
pref("media.videocontrols.picture-in-picture.enabled", false);
|
||||||
pref("media.videocontrols.picture-in-picture.display-text-tracks.enabled", false);
|
|
||||||
pref("media.videocontrols.picture-in-picture.video-toggle.enabled", false);
|
pref("media.videocontrols.picture-in-picture.video-toggle.enabled", false);
|
||||||
pref("media.videocontrols.picture-in-picture.video-toggle.always-show", false);
|
pref("media.videocontrols.picture-in-picture.video-toggle.always-show", false);
|
||||||
pref("media.videocontrols.picture-in-picture.video-toggle.min-video-secs", 45);
|
pref("media.videocontrols.picture-in-picture.video-toggle.min-video-secs", 45);
|
||||||
|
|
|
@ -46,7 +46,6 @@ ChromeUtils.defineModuleGetter(
|
||||||
"resource://gre/modules/ContentDOMReference.jsm"
|
"resource://gre/modules/ContentDOMReference.jsm"
|
||||||
);
|
);
|
||||||
|
|
||||||
const { WebVTT } = ChromeUtils.import("resource://gre/modules/vtt.jsm");
|
|
||||||
const { XPCOMUtils } = ChromeUtils.import(
|
const { XPCOMUtils } = ChromeUtils.import(
|
||||||
"resource://gre/modules/XPCOMUtils.jsm"
|
"resource://gre/modules/XPCOMUtils.jsm"
|
||||||
);
|
);
|
||||||
|
@ -54,12 +53,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||||
AppConstants: "resource://gre/modules/AppConstants.jsm",
|
AppConstants: "resource://gre/modules/AppConstants.jsm",
|
||||||
});
|
});
|
||||||
|
|
||||||
XPCOMUtils.defineLazyPreferenceGetter(
|
|
||||||
this,
|
|
||||||
"DISPLAY_TEXT_TRACKS_PREF",
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled",
|
|
||||||
false
|
|
||||||
);
|
|
||||||
const TOGGLE_ENABLED_PREF =
|
const TOGGLE_ENABLED_PREF =
|
||||||
"media.videocontrols.picture-in-picture.video-toggle.enabled";
|
"media.videocontrols.picture-in-picture.video-toggle.enabled";
|
||||||
const TOGGLE_TESTING_PREF =
|
const TOGGLE_TESTING_PREF =
|
||||||
|
@ -1138,132 +1131,6 @@ class PictureInPictureChild extends JSWindowActorChild {
|
||||||
// A weak reference to this PiP window's content window
|
// A weak reference to this PiP window's content window
|
||||||
weakPlayerContent = null;
|
weakPlayerContent = null;
|
||||||
|
|
||||||
// A reference to current WebVTT track currently displayed on the content window
|
|
||||||
_currentWebVTTTrack = null;
|
|
||||||
|
|
||||||
observerFunction = null;
|
|
||||||
|
|
||||||
observe(subject, topic, data) {
|
|
||||||
if (
|
|
||||||
topic != "nsPref:changed" ||
|
|
||||||
data !==
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled"
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const originatingVideo = this.getWeakVideo();
|
|
||||||
let isTextTrackPrefEnabled = Services.prefs.getBoolPref(
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Enable or disable text track support
|
|
||||||
if (isTextTrackPrefEnabled) {
|
|
||||||
this.setupTextTracks(originatingVideo);
|
|
||||||
} else {
|
|
||||||
this.removeTextTracks(originatingVideo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets up Picture-in-Picture to support displaying text tracks from WebVTT
|
|
||||||
*
|
|
||||||
* If the originating video supports WebVTT, try to read the
|
|
||||||
* active track and cues. Display any active cues on the pip window
|
|
||||||
* right away if applicable.
|
|
||||||
*
|
|
||||||
* @param originatingVideo {Element|null}
|
|
||||||
* The <video> being displayed in Picture-in-Picture mode, or null if that <video> no longer exists.
|
|
||||||
*/
|
|
||||||
setupTextTracks(originatingVideo) {
|
|
||||||
const isWebVTTSupported = !!originatingVideo.textTracks?.length;
|
|
||||||
|
|
||||||
if (!isWebVTTSupported) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify active track for originating video
|
|
||||||
this.setActiveTextTrack(originatingVideo.textTracks);
|
|
||||||
|
|
||||||
if (!this._currentWebVTTTrack) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for changes in tracks and active cues
|
|
||||||
originatingVideo.textTracks.addEventListener("change", this);
|
|
||||||
this._currentWebVTTTrack.addEventListener("cuechange", this.onCueChange);
|
|
||||||
|
|
||||||
const cues = this._currentWebVTTTrack.activeCues;
|
|
||||||
this.updateWebVTTTextTracksDisplay(cues);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes existing text tracks on the Picture in Picture window.
|
|
||||||
*
|
|
||||||
* If the originating video supports WebVTT, clear references to active
|
|
||||||
* tracks and cues. No longer listen for any track or cue changes.
|
|
||||||
*
|
|
||||||
* @param originatingVideo {Element|null}
|
|
||||||
* The <video> being displayed in Picture-in-Picture mode, or null if that <video> no longer exists.
|
|
||||||
*/
|
|
||||||
removeTextTracks(originatingVideo) {
|
|
||||||
const isWebVTTSupported = !!originatingVideo.textTracks;
|
|
||||||
|
|
||||||
if (!isWebVTTSupported) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No longer listen for changes to tracks and active cues
|
|
||||||
originatingVideo.textTracks.removeEventListener("change", this);
|
|
||||||
this._currentWebVTTTrack?.removeEventListener(
|
|
||||||
"cuechange",
|
|
||||||
this.onCueChange
|
|
||||||
);
|
|
||||||
this._currentWebVTTTrack = null;
|
|
||||||
this.updateWebVTTTextTracksDisplay(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the text content for the container that holds and displays text tracks
|
|
||||||
* on the pip window.
|
|
||||||
* @param textTrackCues {TextTrackCueList|null}
|
|
||||||
* Collection of TextTrackCue objects containing text displayed, or null if there is no cue to display.
|
|
||||||
*/
|
|
||||||
updateWebVTTTextTracksDisplay(textTrackCues) {
|
|
||||||
let pipWindowTracksContainer = this.document.getElementById("texttracks");
|
|
||||||
let playerVideo = this.document.getElementById("playervideo");
|
|
||||||
let playerVideoWindow = playerVideo.ownerGlobal;
|
|
||||||
|
|
||||||
// To prevent overlap with previous cues, clear all text from the pip window
|
|
||||||
pipWindowTracksContainer.replaceChildren();
|
|
||||||
|
|
||||||
if (!textTrackCues) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const allCuesArray = [...textTrackCues];
|
|
||||||
let lineNumberUsed = allCuesArray.find(cue => cue.line !== "auto");
|
|
||||||
|
|
||||||
// If VTTCue.line is not set to "auto", simplying reading textTrackCues does
|
|
||||||
// not guarantee that text tracks are displayed in their intended order. In this case,
|
|
||||||
// sort the cues according to line number.
|
|
||||||
if (lineNumberUsed) {
|
|
||||||
allCuesArray.sort((cue1, cue2) => cue1.line - cue2.line);
|
|
||||||
}
|
|
||||||
// Parse through WebVTT cue using vtt.js to ensure
|
|
||||||
// semantic markup like <b> and <i> tags are rendered.
|
|
||||||
allCuesArray.forEach(cue => {
|
|
||||||
let text = cue.text;
|
|
||||||
let cueTextNode = WebVTT.convertCueToDOMTree(playerVideoWindow, text);
|
|
||||||
let cueDiv = this.document.createElement("div");
|
|
||||||
cueDiv.appendChild(cueTextNode);
|
|
||||||
// Whitespaces are usually collapsed. Set to pre-wrap
|
|
||||||
// so that newlines are rendered.
|
|
||||||
cueDiv.style = "white-space: pre;";
|
|
||||||
pipWindowTracksContainer.appendChild(cueDiv);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a reference to the PiP's <video> element being displayed in Picture-in-Picture
|
* Returns a reference to the PiP's <video> element being displayed in Picture-in-Picture
|
||||||
* mode.
|
* mode.
|
||||||
|
@ -1381,36 +1248,6 @@ class PictureInPictureChild extends JSWindowActorChild {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "change": {
|
|
||||||
// Clear currently stored track data (webvtt support) before reading
|
|
||||||
// a new track.
|
|
||||||
if (this._currentWebVTTTrack) {
|
|
||||||
this._currentWebVTTTrack.removeEventListener(
|
|
||||||
"cuechange",
|
|
||||||
this.onCueChange
|
|
||||||
);
|
|
||||||
this._currentWebVTTTrack = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const tracks = event.target;
|
|
||||||
this.setActiveTextTrack(tracks);
|
|
||||||
const isCurrentTrackAvailable = this._currentWebVTTTrack;
|
|
||||||
|
|
||||||
// If tracks are disabled or invalid while change occurs,
|
|
||||||
// remove text tracks from the pip window and stop here.
|
|
||||||
if (!isCurrentTrackAvailable || !tracks.length) {
|
|
||||||
this.updateWebVTTTextTracksDisplay(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._currentWebVTTTrack.addEventListener(
|
|
||||||
"cuechange",
|
|
||||||
this.onCueChange
|
|
||||||
);
|
|
||||||
const cues = this._currentWebVTTTrack.activeCues;
|
|
||||||
this.updateWebVTTTextTracksDisplay(cues);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1490,38 +1327,12 @@ class PictureInPictureChild extends JSWindowActorChild {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates this._currentWebVTTTrack if an active track is found
|
|
||||||
* for the originating video.
|
|
||||||
* @param {TextTrackList} textTrackList list of text tracks
|
|
||||||
*/
|
|
||||||
setActiveTextTrack(textTrackList) {
|
|
||||||
this._currentWebVTTTrack = null;
|
|
||||||
|
|
||||||
for (let i = 0; i < textTrackList.length; i++) {
|
|
||||||
let track = textTrackList[i];
|
|
||||||
let isCCText = track.kind === "subtitles" || track.kind === "captions";
|
|
||||||
if (isCCText && track.mode === "showing") {
|
|
||||||
this._currentWebVTTTrack = track;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keeps an eye on the originating video's document. If it ever
|
* Keeps an eye on the originating video's document. If it ever
|
||||||
* goes away, this will cause the Picture-in-Picture window for any
|
* goes away, this will cause the Picture-in-Picture window for any
|
||||||
* of its content to go away as well.
|
* of its content to go away as well.
|
||||||
*/
|
*/
|
||||||
trackOriginatingVideo(originatingVideo) {
|
trackOriginatingVideo(originatingVideo) {
|
||||||
this.observerFunction = (subject, topic, data) => {
|
|
||||||
this.observe(subject, topic, data);
|
|
||||||
};
|
|
||||||
Services.prefs.addObserver(
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled",
|
|
||||||
this.observerFunction
|
|
||||||
);
|
|
||||||
|
|
||||||
let originatingWindow = originatingVideo.ownerGlobal;
|
let originatingWindow = originatingVideo.ownerGlobal;
|
||||||
if (originatingWindow) {
|
if (originatingWindow) {
|
||||||
originatingWindow.addEventListener("pagehide", this);
|
originatingWindow.addEventListener("pagehide", this);
|
||||||
|
@ -1530,10 +1341,6 @@ class PictureInPictureChild extends JSWindowActorChild {
|
||||||
originatingVideo.addEventListener("volumechange", this);
|
originatingVideo.addEventListener("volumechange", this);
|
||||||
originatingVideo.addEventListener("resize", this);
|
originatingVideo.addEventListener("resize", this);
|
||||||
|
|
||||||
if (DISPLAY_TEXT_TRACKS_PREF) {
|
|
||||||
this.setupTextTracks(originatingVideo);
|
|
||||||
}
|
|
||||||
|
|
||||||
let chromeEventHandler = originatingWindow.docShell.chromeEventHandler;
|
let chromeEventHandler = originatingWindow.docShell.chromeEventHandler;
|
||||||
chromeEventHandler.addEventListener(
|
chromeEventHandler.addEventListener(
|
||||||
"MozDOMFullscreen:Request",
|
"MozDOMFullscreen:Request",
|
||||||
|
@ -1555,11 +1362,6 @@ class PictureInPictureChild extends JSWindowActorChild {
|
||||||
* window's document unloads.
|
* window's document unloads.
|
||||||
*/
|
*/
|
||||||
untrackOriginatingVideo(originatingVideo) {
|
untrackOriginatingVideo(originatingVideo) {
|
||||||
Services.prefs.removeObserver(
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled",
|
|
||||||
this.observerFunction
|
|
||||||
);
|
|
||||||
|
|
||||||
let originatingWindow = originatingVideo.ownerGlobal;
|
let originatingWindow = originatingVideo.ownerGlobal;
|
||||||
if (originatingWindow) {
|
if (originatingWindow) {
|
||||||
originatingWindow.removeEventListener("pagehide", this);
|
originatingWindow.removeEventListener("pagehide", this);
|
||||||
|
@ -1568,10 +1370,6 @@ class PictureInPictureChild extends JSWindowActorChild {
|
||||||
originatingVideo.removeEventListener("volumechange", this);
|
originatingVideo.removeEventListener("volumechange", this);
|
||||||
originatingVideo.removeEventListener("resize", this);
|
originatingVideo.removeEventListener("resize", this);
|
||||||
|
|
||||||
if (DISPLAY_TEXT_TRACKS_PREF) {
|
|
||||||
this.removeTextTracks(originatingVideo);
|
|
||||||
}
|
|
||||||
|
|
||||||
let chromeEventHandler = originatingWindow.docShell.chromeEventHandler;
|
let chromeEventHandler = originatingWindow.docShell.chromeEventHandler;
|
||||||
chromeEventHandler.removeEventListener(
|
chromeEventHandler.removeEventListener(
|
||||||
"MozDOMFullscreen:Request",
|
"MozDOMFullscreen:Request",
|
||||||
|
@ -1665,8 +1463,6 @@ class PictureInPictureChild extends JSWindowActorChild {
|
||||||
|
|
||||||
let doc = this.document;
|
let doc = this.document;
|
||||||
let playerVideo = doc.createElement("video");
|
let playerVideo = doc.createElement("video");
|
||||||
playerVideo.id = "playervideo";
|
|
||||||
let textTracks = doc.createElement("div");
|
|
||||||
|
|
||||||
doc.body.style.overflow = "hidden";
|
doc.body.style.overflow = "hidden";
|
||||||
doc.body.style.margin = "0";
|
doc.body.style.margin = "0";
|
||||||
|
@ -1674,22 +1470,10 @@ class PictureInPictureChild extends JSWindowActorChild {
|
||||||
// Force the player video to assume maximum height and width of the
|
// Force the player video to assume maximum height and width of the
|
||||||
// containing window
|
// containing window
|
||||||
playerVideo.style.height = "100vh";
|
playerVideo.style.height = "100vh";
|
||||||
|
playerVideo.style.width = "100vw";
|
||||||
playerVideo.style.backgroundColor = "#000";
|
playerVideo.style.backgroundColor = "#000";
|
||||||
|
|
||||||
// Load text tracks container in the content process so that
|
|
||||||
// we can load text tracks without having to constantly
|
|
||||||
// access the parent process.
|
|
||||||
textTracks.id = "texttracks";
|
|
||||||
// TODO: responsive styling. Hardcoded values until design spec confirmed.
|
|
||||||
textTracks.style.position = "absolute";
|
|
||||||
textTracks.style.textAlign = "center";
|
|
||||||
textTracks.style.width = "100vw";
|
|
||||||
textTracks.style.bottom = "30px";
|
|
||||||
textTracks.style.backgroundColor = "black";
|
|
||||||
textTracks.style.color = "white";
|
|
||||||
|
|
||||||
doc.body.appendChild(playerVideo);
|
doc.body.appendChild(playerVideo);
|
||||||
doc.body.appendChild(textTracks);
|
|
||||||
|
|
||||||
originatingVideo.cloneElementVisually(playerVideo);
|
originatingVideo.cloneElementVisually(playerVideo);
|
||||||
|
|
||||||
|
@ -1699,7 +1483,6 @@ class PictureInPictureChild extends JSWindowActorChild {
|
||||||
playerVideo.style.transform = "scaleX(-1)";
|
playerVideo.style.transform = "scaleX(-1)";
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onCueChange = this.onCueChange.bind(this);
|
|
||||||
this.trackOriginatingVideo(originatingVideo);
|
this.trackOriginatingVideo(originatingVideo);
|
||||||
|
|
||||||
this.contentWindow.addEventListener(
|
this.contentWindow.addEventListener(
|
||||||
|
@ -1744,15 +1527,6 @@ class PictureInPictureChild extends JSWindowActorChild {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onCueChange(e) {
|
|
||||||
if (!DISPLAY_TEXT_TRACKS_PREF) {
|
|
||||||
this.updateWebVTTTextTracksDisplay(null);
|
|
||||||
} else {
|
|
||||||
const cues = this._currentWebVTTTrack.activeCues;
|
|
||||||
this.updateWebVTTTextTracksDisplay(cues);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This checks if a given keybinding has been disabled for the specific site
|
* This checks if a given keybinding has been disabled for the specific site
|
||||||
* currently being viewed.
|
* currently being viewed.
|
||||||
|
|
|
@ -7,7 +7,6 @@ support-files =
|
||||||
test-page.html
|
test-page.html
|
||||||
test-page-with-iframe.html
|
test-page-with-iframe.html
|
||||||
test-page-with-sound.html
|
test-page-with-sound.html
|
||||||
test-page-with-webvtt.html
|
|
||||||
test-pointer-events-none.html
|
test-pointer-events-none.html
|
||||||
test-transparent-overlay-1.html
|
test-transparent-overlay-1.html
|
||||||
test-transparent-overlay-2.html
|
test-transparent-overlay-2.html
|
||||||
|
@ -18,15 +17,11 @@ support-files =
|
||||||
test-video-cropped.mp4
|
test-video-cropped.mp4
|
||||||
test-video-vertical.mp4
|
test-video-vertical.mp4
|
||||||
test-video-long.mp4
|
test-video-long.mp4
|
||||||
test-webvtt-1.vtt
|
|
||||||
test-webvtt-2.vtt
|
|
||||||
test-webvtt-3.vtt
|
|
||||||
short.mp4
|
short.mp4
|
||||||
../../../../dom/media/test/gizmo.mp4
|
../../../../dom/media/test/gizmo.mp4
|
||||||
../../../../dom/media/test/owl.mp3
|
../../../../dom/media/test/owl.mp3
|
||||||
|
|
||||||
prefs =
|
prefs =
|
||||||
media.videocontrols.picture-in-picture.display-text-tracks.enabled=false
|
|
||||||
media.videocontrols.picture-in-picture.enabled=true
|
media.videocontrols.picture-in-picture.enabled=true
|
||||||
media.videocontrols.picture-in-picture.video-toggle.enabled=true
|
media.videocontrols.picture-in-picture.video-toggle.enabled=true
|
||||||
media.videocontrols.picture-in-picture.video-toggle.testing=true
|
media.videocontrols.picture-in-picture.video-toggle.testing=true
|
||||||
|
@ -82,8 +77,6 @@ skip-if = os == "win" && bits == 64 && debug # Bug 1683002
|
||||||
[browser_stripVideoStyles.js]
|
[browser_stripVideoStyles.js]
|
||||||
[browser_tabIconOverlayPiP.js]
|
[browser_tabIconOverlayPiP.js]
|
||||||
[browser_telemetry_togglePiP.js]
|
[browser_telemetry_togglePiP.js]
|
||||||
[browser_text_tracks_webvtt_1.js]
|
|
||||||
[browser_text_tracks_webvtt_2.js]
|
|
||||||
[browser_thirdPartyIframe.js]
|
[browser_thirdPartyIframe.js]
|
||||||
[browser_toggleButtonOnNanDuration.js]
|
[browser_toggleButtonOnNanDuration.js]
|
||||||
skip-if =
|
skip-if =
|
||||||
|
|
|
@ -1,168 +0,0 @@
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes videos and text tracks for the current test case.
|
|
||||||
* First track is the default track to be loaded onto the video.
|
|
||||||
* Once initialization is done, play then pause the requested video.
|
|
||||||
* so that text tracks are loaded.
|
|
||||||
* @param {Element} browser The <xul:browser> hosting the <video>
|
|
||||||
* @param {String} videoID The ID of the video being checked
|
|
||||||
* @param {Integer} defaultTrackIndex The index of the track to be loaded, or none if -1
|
|
||||||
*/
|
|
||||||
async function prepareVideosAndTracks(browser, videoID, defaultTrackIndex = 0) {
|
|
||||||
info("Preparing video and initial text tracks");
|
|
||||||
await ensureVideosReady(browser);
|
|
||||||
await SpecialPowers.spawn(
|
|
||||||
browser,
|
|
||||||
[{ videoID, defaultTrackIndex }],
|
|
||||||
async args => {
|
|
||||||
let video = content.document.getElementById(args.videoID);
|
|
||||||
let tracks = video.textTracks;
|
|
||||||
|
|
||||||
is(tracks.length, 3, "Number of tracks loaded should be 3");
|
|
||||||
|
|
||||||
// Enable track for originating video
|
|
||||||
if (args.defaultTrackIndex >= 0) {
|
|
||||||
info(`Loading track ${args.defaultTrackIndex + 1}`);
|
|
||||||
let track = tracks[args.defaultTrackIndex];
|
|
||||||
tracks.mode = "showing";
|
|
||||||
track.mode = "showing";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Briefly play the video to load text tracks onto the pip window.
|
|
||||||
info("Playing video to load text tracks");
|
|
||||||
video.play();
|
|
||||||
info("Pausing video");
|
|
||||||
video.pause();
|
|
||||||
ok(video.paused, "Video should be paused before proceeding with test");
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This test ensures that text tracks shown on the source video
|
|
||||||
* do not appear on a newly created pip window if the pref
|
|
||||||
* is disabled.
|
|
||||||
*/
|
|
||||||
add_task(async function test_text_tracks_new_window_pref_disabled() {
|
|
||||||
info("Running test: new window - pref disabled");
|
|
||||||
await SpecialPowers.pushPrefEnv({
|
|
||||||
set: [
|
|
||||||
[
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled",
|
|
||||||
false,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
});
|
|
||||||
let videoID = "with-controls";
|
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
|
||||||
{
|
|
||||||
url: TEST_PAGE_WITH_WEBVTT,
|
|
||||||
gBrowser,
|
|
||||||
},
|
|
||||||
async browser => {
|
|
||||||
await prepareVideosAndTracks(browser, videoID);
|
|
||||||
|
|
||||||
let pipWin = await triggerPictureInPicture(browser, videoID);
|
|
||||||
ok(pipWin, "Got Picture-in-Picture window.");
|
|
||||||
let pipBrowser = pipWin.document.getElementById("browser");
|
|
||||||
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
info("Checking text track content in pip window");
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
|
|
||||||
ok(textTracks, "TextTracks container should exist in the pip window");
|
|
||||||
ok(
|
|
||||||
!textTracks.textContent,
|
|
||||||
"Text tracks should not be visible on the pip window"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This test ensures that text tracks shown on the source video
|
|
||||||
* appear on a newly created pip window if the pref is enabled.
|
|
||||||
*/
|
|
||||||
add_task(async function test_text_tracks_new_window_pref_enabled() {
|
|
||||||
info("Running test: new window - pref enabled");
|
|
||||||
await SpecialPowers.pushPrefEnv({
|
|
||||||
set: [
|
|
||||||
[
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled",
|
|
||||||
true,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
});
|
|
||||||
let videoID = "with-controls";
|
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
|
||||||
{
|
|
||||||
url: TEST_PAGE_WITH_WEBVTT,
|
|
||||||
gBrowser,
|
|
||||||
},
|
|
||||||
async browser => {
|
|
||||||
await prepareVideosAndTracks(browser, videoID);
|
|
||||||
|
|
||||||
let pipWin = await triggerPictureInPicture(browser, videoID);
|
|
||||||
ok(pipWin, "Got Picture-in-Picture window.");
|
|
||||||
let pipBrowser = pipWin.document.getElementById("browser");
|
|
||||||
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
info("Checking text track content in pip window");
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
ok(textTracks, "TextTracks container should exist in the pip window");
|
|
||||||
await ContentTaskUtils.waitForCondition(() => {
|
|
||||||
return textTracks.textContent;
|
|
||||||
}, `Text track is still not visible on the pip window. Got ${textTracks.textContent}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This test ensures that text tracks do not appear on a new pip window
|
|
||||||
* if no track is loaded and the pref is enabled.
|
|
||||||
*/
|
|
||||||
add_task(async function test_text_tracks_new_window_no_track() {
|
|
||||||
info("Running test: new window - no track");
|
|
||||||
await SpecialPowers.pushPrefEnv({
|
|
||||||
set: [
|
|
||||||
[
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled",
|
|
||||||
true,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
});
|
|
||||||
let videoID = "with-controls";
|
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
|
||||||
{
|
|
||||||
url: TEST_PAGE_WITH_WEBVTT,
|
|
||||||
gBrowser,
|
|
||||||
},
|
|
||||||
async browser => {
|
|
||||||
await prepareVideosAndTracks(browser, videoID, -1);
|
|
||||||
|
|
||||||
let pipWin = await triggerPictureInPicture(browser, videoID);
|
|
||||||
ok(pipWin, "Got Picture-in-Picture window.");
|
|
||||||
let pipBrowser = pipWin.document.getElementById("browser");
|
|
||||||
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
info("Checking text track content in pip window");
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
|
|
||||||
ok(textTracks, "TextTracks container should exist in the pip window");
|
|
||||||
ok(
|
|
||||||
!textTracks.textContent,
|
|
||||||
"Text tracks should not be visible on the pip window"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
|
@ -1,443 +0,0 @@
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes videos and text tracks for the current test case.
|
|
||||||
* First track is the default track to be loaded onto the video.
|
|
||||||
* Once initialization is done, play then pause the requested video.
|
|
||||||
* so that text tracks are loaded.
|
|
||||||
* @param {Element} browser The <xul:browser> hosting the <video>
|
|
||||||
* @param {String} videoID The ID of the video being checked
|
|
||||||
* @param {Integer} defaultTrackIndex The index of the track to be loaded, or none if -1
|
|
||||||
*/
|
|
||||||
async function prepareVideosAndTracks(browser, videoID, defaultTrackIndex = 0) {
|
|
||||||
info("Preparing video and initial text tracks");
|
|
||||||
await ensureVideosReady(browser);
|
|
||||||
await SpecialPowers.spawn(
|
|
||||||
browser,
|
|
||||||
[{ videoID, defaultTrackIndex }],
|
|
||||||
async args => {
|
|
||||||
let video = content.document.getElementById(args.videoID);
|
|
||||||
let tracks = video.textTracks;
|
|
||||||
|
|
||||||
is(tracks.length, 3, "Number of tracks loaded should be 3");
|
|
||||||
|
|
||||||
// Enable track for originating video
|
|
||||||
if (args.defaultTrackIndex >= 0) {
|
|
||||||
info(`Loading track ${args.defaultTrackIndex + 1}`);
|
|
||||||
let track = tracks[args.defaultTrackIndex];
|
|
||||||
tracks.mode = "showing";
|
|
||||||
track.mode = "showing";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Briefly play the video to load text tracks onto the pip window.
|
|
||||||
info("Playing video to load text tracks");
|
|
||||||
video.play();
|
|
||||||
info("Pausing video");
|
|
||||||
video.pause();
|
|
||||||
ok(video.paused, "Video should be paused before proceeding with test");
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Plays originating video until the next cue is loaded.
|
|
||||||
* Once the next cue is loaded, pause the video.
|
|
||||||
* @param {Element} browser The <xul:browser> hosting the <video>
|
|
||||||
* @param {String} videoID The ID of the video being checked
|
|
||||||
* @param {Integer} textTrackIndex The index of the track to be loaded, or none if -1
|
|
||||||
*/
|
|
||||||
async function waitForNextCue(browser, videoID, textTrackIndex = 0) {
|
|
||||||
if (textTrackIndex < 0) {
|
|
||||||
ok(false, "Cannot wait for next cue with invalid track index");
|
|
||||||
}
|
|
||||||
|
|
||||||
await SpecialPowers.spawn(
|
|
||||||
browser,
|
|
||||||
[{ videoID, textTrackIndex }],
|
|
||||||
async args => {
|
|
||||||
let video = content.document.getElementById(args.videoID);
|
|
||||||
info("Playing video to activate next cue");
|
|
||||||
video.play();
|
|
||||||
ok(!video.paused, "Video is playing");
|
|
||||||
|
|
||||||
info("Waiting until cuechange is called");
|
|
||||||
await ContentTaskUtils.waitForEvent(
|
|
||||||
video.textTracks[args.textTrackIndex],
|
|
||||||
"cuechange"
|
|
||||||
);
|
|
||||||
|
|
||||||
info("Pausing video to read text track");
|
|
||||||
video.pause();
|
|
||||||
ok(video.paused, "Video is paused");
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This test ensures that text tracks disappear from the pip window
|
|
||||||
* when the pref is disabled.
|
|
||||||
*/
|
|
||||||
add_task(async function test_text_tracks_existing_window_pref_disabled() {
|
|
||||||
info("Running test: existing window - pref disabled");
|
|
||||||
await SpecialPowers.pushPrefEnv({
|
|
||||||
set: [
|
|
||||||
[
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled",
|
|
||||||
true,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
});
|
|
||||||
let videoID = "with-controls";
|
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
|
||||||
{
|
|
||||||
url: TEST_PAGE_WITH_WEBVTT,
|
|
||||||
gBrowser,
|
|
||||||
},
|
|
||||||
async browser => {
|
|
||||||
await prepareVideosAndTracks(browser, videoID);
|
|
||||||
|
|
||||||
let pipWin = await triggerPictureInPicture(browser, videoID);
|
|
||||||
ok(pipWin, "Got Picture-in-Picture window.");
|
|
||||||
let pipBrowser = pipWin.document.getElementById("browser");
|
|
||||||
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
info("Checking text track content in pip window");
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
ok(textTracks, "TextTracks container should exist in the pip window");
|
|
||||||
await ContentTaskUtils.waitForCondition(() => {
|
|
||||||
return textTracks.textContent;
|
|
||||||
}, `Text track is still not visible on the pip window. Got ${textTracks.textContent}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
info("Turning off pref");
|
|
||||||
await SpecialPowers.popPrefEnv();
|
|
||||||
await SpecialPowers.pushPrefEnv({
|
|
||||||
set: [
|
|
||||||
[
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled",
|
|
||||||
false,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
// Verify that cue is no longer on the pip window
|
|
||||||
info("Checking that cue is no longer on pip window");
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
await ContentTaskUtils.waitForCondition(() => {
|
|
||||||
return !textTracks.textContent;
|
|
||||||
}, `Text track is still visible on the pip window. Got ${textTracks.textContent}`);
|
|
||||||
info("Successfully removed text tracks from pip window");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This test ensures that text tracks shown on the source video
|
|
||||||
* window appear on an existing pip window when the pref is enabled.
|
|
||||||
*/
|
|
||||||
add_task(async function test_text_tracks_existing_window_pref_enabled() {
|
|
||||||
info("Running test: existing window - pref enabled");
|
|
||||||
await SpecialPowers.pushPrefEnv({
|
|
||||||
set: [
|
|
||||||
[
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled",
|
|
||||||
false,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
});
|
|
||||||
let videoID = "with-controls";
|
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
|
||||||
{
|
|
||||||
url: TEST_PAGE_WITH_WEBVTT,
|
|
||||||
gBrowser,
|
|
||||||
},
|
|
||||||
async browser => {
|
|
||||||
await prepareVideosAndTracks(browser, videoID);
|
|
||||||
|
|
||||||
let pipWin = await triggerPictureInPicture(browser, videoID);
|
|
||||||
ok(pipWin, "Got Picture-in-Picture window.");
|
|
||||||
let pipBrowser = pipWin.document.getElementById("browser");
|
|
||||||
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
info("Checking text track content in pip window");
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
|
|
||||||
ok(textTracks, "TextTracks container should exist in the pip window");
|
|
||||||
ok(
|
|
||||||
!textTracks.textContent,
|
|
||||||
"Text tracks should not be visible on the pip window"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
info("Turning on pref");
|
|
||||||
await SpecialPowers.popPrefEnv();
|
|
||||||
await SpecialPowers.pushPrefEnv({
|
|
||||||
set: [
|
|
||||||
[
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled",
|
|
||||||
true,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
info("Checking that cue is on pip window");
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
await ContentTaskUtils.waitForCondition(() => {
|
|
||||||
return textTracks.textContent;
|
|
||||||
}, `Text track is still not visible on the pip window. Got ${textTracks.textContent}`);
|
|
||||||
info("Successfully displayed text tracks on pip window");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This test ensures that text tracks update to the correct track
|
|
||||||
* when a new track is selected.
|
|
||||||
*/
|
|
||||||
add_task(async function test_text_tracks_existing_window_new_track() {
|
|
||||||
info("Running test: existing window - new track");
|
|
||||||
await SpecialPowers.pushPrefEnv({
|
|
||||||
set: [
|
|
||||||
[
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled",
|
|
||||||
true,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
});
|
|
||||||
let videoID = "with-controls";
|
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
|
||||||
{
|
|
||||||
url: TEST_PAGE_WITH_WEBVTT,
|
|
||||||
gBrowser,
|
|
||||||
},
|
|
||||||
async browser => {
|
|
||||||
await prepareVideosAndTracks(browser, videoID);
|
|
||||||
|
|
||||||
let pipWin = await triggerPictureInPicture(browser, videoID);
|
|
||||||
ok(pipWin, "Got Picture-in-Picture window.");
|
|
||||||
let pipBrowser = pipWin.document.getElementById("browser");
|
|
||||||
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
info("Checking text track content in pip window");
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
ok(textTracks, "TextTracks container should exist in the pip window");
|
|
||||||
await ContentTaskUtils.waitForCondition(() => {
|
|
||||||
return textTracks.textContent;
|
|
||||||
}, `Text track is still not visible on the pip window. Got ${textTracks.textContent}`);
|
|
||||||
ok(
|
|
||||||
textTracks.textContent.includes("track 1"),
|
|
||||||
"Track 1 should be loaded"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Change track in the content window
|
|
||||||
await SpecialPowers.spawn(browser, [videoID], async videoID => {
|
|
||||||
let video = content.document.getElementById(videoID);
|
|
||||||
let tracks = video.textTracks;
|
|
||||||
|
|
||||||
info("Changing to a new track");
|
|
||||||
let track1 = tracks[0];
|
|
||||||
track1.mode = "disabled";
|
|
||||||
let track2 = tracks[1];
|
|
||||||
track2.mode = "showing";
|
|
||||||
});
|
|
||||||
|
|
||||||
// Ensure new track is loaded
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
info("Checking new text track content in pip window");
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
|
|
||||||
await ContentTaskUtils.waitForCondition(() => {
|
|
||||||
return textTracks.textContent;
|
|
||||||
}, `Text track is still not visible on the pip window. Got ${textTracks.textContent}`);
|
|
||||||
ok(
|
|
||||||
textTracks.textContent.includes("track 2"),
|
|
||||||
"Track 2 should be loaded"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This test ensures that text tracks are correctly updated.
|
|
||||||
*/
|
|
||||||
add_task(async function test_text_tracks_existing_window_cues() {
|
|
||||||
info("Running test: existing window - cues");
|
|
||||||
await SpecialPowers.pushPrefEnv({
|
|
||||||
set: [
|
|
||||||
[
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled",
|
|
||||||
true,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
});
|
|
||||||
let videoID = "with-controls";
|
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
|
||||||
{
|
|
||||||
url: TEST_PAGE_WITH_WEBVTT,
|
|
||||||
gBrowser,
|
|
||||||
},
|
|
||||||
async browser => {
|
|
||||||
await prepareVideosAndTracks(browser, videoID);
|
|
||||||
|
|
||||||
let pipWin = await triggerPictureInPicture(browser, videoID);
|
|
||||||
ok(pipWin, "Got Picture-in-Picture window.");
|
|
||||||
let pipBrowser = pipWin.document.getElementById("browser");
|
|
||||||
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
ok(textTracks, "TextTracks container should exist in the pip window");
|
|
||||||
|
|
||||||
// Verify that first cue appears
|
|
||||||
info("Checking first cue on pip window");
|
|
||||||
await ContentTaskUtils.waitForCondition(() => {
|
|
||||||
return textTracks.textContent;
|
|
||||||
}, `Text track is still not visible on the pip window. Got ${textTracks.textContent}`);
|
|
||||||
ok(
|
|
||||||
textTracks.textContent.includes("cue 1"),
|
|
||||||
`Expected text should be displayed on the pip window. Got ${textTracks.textContent}.`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Play video to move to the next cue
|
|
||||||
await waitForNextCue(browser, videoID);
|
|
||||||
|
|
||||||
// Test remaining cues
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
|
|
||||||
// Verify that empty cue makes text disappear
|
|
||||||
info("Checking empty cue in pip window");
|
|
||||||
ok(
|
|
||||||
!textTracks.textContent,
|
|
||||||
"Text track should not be visible on the pip window"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
await waitForNextCue(browser, videoID);
|
|
||||||
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
// Verify that second cue appears
|
|
||||||
info("Checking second cue in pip window");
|
|
||||||
ok(
|
|
||||||
textTracks.textContent.includes("cue 2"),
|
|
||||||
"Text track second cue should be visible on the pip window"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This test ensures that text tracks disappear if no track is selected.
|
|
||||||
*/
|
|
||||||
add_task(async function test_text_tracks_existing_window_no_track() {
|
|
||||||
info("Running test: existing window - no track");
|
|
||||||
await SpecialPowers.pushPrefEnv({
|
|
||||||
set: [
|
|
||||||
[
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled",
|
|
||||||
true,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
});
|
|
||||||
let videoID = "with-controls";
|
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
|
||||||
{
|
|
||||||
url: TEST_PAGE_WITH_WEBVTT,
|
|
||||||
gBrowser,
|
|
||||||
},
|
|
||||||
async browser => {
|
|
||||||
await prepareVideosAndTracks(browser, videoID);
|
|
||||||
|
|
||||||
let pipWin = await triggerPictureInPicture(browser, videoID);
|
|
||||||
ok(pipWin, "Got Picture-in-Picture window.");
|
|
||||||
let pipBrowser = pipWin.document.getElementById("browser");
|
|
||||||
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
info("Checking text track content in pip window");
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
ok(textTracks, "TextTracks container should exist in the pip window");
|
|
||||||
await ContentTaskUtils.waitForCondition(() => {
|
|
||||||
return textTracks.textContent;
|
|
||||||
}, `Text track is still not visible on the pip window. Got ${textTracks.textContent}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove track in the content window
|
|
||||||
await SpecialPowers.spawn(browser, [videoID], async videoID => {
|
|
||||||
let video = content.document.getElementById(videoID);
|
|
||||||
let tracks = video.textTracks;
|
|
||||||
|
|
||||||
info("Removing tracks");
|
|
||||||
let track1 = tracks[0];
|
|
||||||
track1.mode = "disabled";
|
|
||||||
let track2 = tracks[1];
|
|
||||||
track2.mode = "disabled";
|
|
||||||
});
|
|
||||||
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
info("Checking that text track disappears from pip window");
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
|
|
||||||
await ContentTaskUtils.waitForCondition(() => {
|
|
||||||
return !textTracks.textContent;
|
|
||||||
}, `Text track is still visible on the pip window. Got ${textTracks.textContent}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This test ensures that text tracks appear correctly if there are multiple active cues.
|
|
||||||
*/
|
|
||||||
add_task(async function test_text_tracks_existing_window_multi_cue() {
|
|
||||||
info("Running test: existing window - multi cue");
|
|
||||||
await SpecialPowers.pushPrefEnv({
|
|
||||||
set: [
|
|
||||||
[
|
|
||||||
"media.videocontrols.picture-in-picture.display-text-tracks.enabled",
|
|
||||||
true,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
});
|
|
||||||
let videoID = "with-controls";
|
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
|
||||||
{
|
|
||||||
url: TEST_PAGE_WITH_WEBVTT,
|
|
||||||
gBrowser,
|
|
||||||
},
|
|
||||||
async browser => {
|
|
||||||
await prepareVideosAndTracks(browser, videoID, 2);
|
|
||||||
let pipWin = await triggerPictureInPicture(browser, videoID);
|
|
||||||
ok(pipWin, "Got Picture-in-Picture window.");
|
|
||||||
let pipBrowser = pipWin.document.getElementById("browser");
|
|
||||||
|
|
||||||
await SpecialPowers.spawn(pipBrowser, [], async () => {
|
|
||||||
info("Checking text track content in pip window");
|
|
||||||
let textTracks = content.document.getElementById("texttracks");
|
|
||||||
|
|
||||||
// Verify multiple active cues
|
|
||||||
ok(textTracks, "TextTracks container should exist in the pip window");
|
|
||||||
await ContentTaskUtils.waitForCondition(() => {
|
|
||||||
return textTracks.textContent;
|
|
||||||
}, `Text track is still not visible on the pip window. Got ${textTracks.textContent}`);
|
|
||||||
is(textTracks.children.length, 2, "Text tracks should load 2 cues");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
|
@ -21,7 +21,6 @@ const TEST_PAGE_WITH_IFRAME = TEST_ROOT_2 + "test-page-with-iframe.html";
|
||||||
const TEST_PAGE_WITH_SOUND = TEST_ROOT + "test-page-with-sound.html";
|
const TEST_PAGE_WITH_SOUND = TEST_ROOT + "test-page-with-sound.html";
|
||||||
const TEST_PAGE_WITH_NAN_VIDEO_DURATION =
|
const TEST_PAGE_WITH_NAN_VIDEO_DURATION =
|
||||||
TEST_ROOT + "test-page-with-nan-video-duration.html";
|
TEST_ROOT + "test-page-with-nan-video-duration.html";
|
||||||
const TEST_PAGE_WITH_WEBVTT = TEST_ROOT + "test-page-with-webvtt.html";
|
|
||||||
const WINDOW_TYPE = "Toolkit:PictureInPicture";
|
const WINDOW_TYPE = "Toolkit:PictureInPicture";
|
||||||
const TOGGLE_POSITION_PREF =
|
const TOGGLE_POSITION_PREF =
|
||||||
"media.videocontrols.picture-in-picture.video-toggle.position";
|
"media.videocontrols.picture-in-picture.video-toggle.position";
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Picture-in-Picture tests</title>
|
|
||||||
<script type="text/javascript" src="click-event-helper.js"></script>
|
|
||||||
</head>
|
|
||||||
<style>
|
|
||||||
video {
|
|
||||||
display: block;
|
|
||||||
border: 1px solid black;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<body>
|
|
||||||
<h1>Video with controls</h1>
|
|
||||||
<video id="with-controls" src="test-video-long.mp4" controls loop="true" width="400" height="225">
|
|
||||||
<track
|
|
||||||
id="track1"
|
|
||||||
kind="captions"
|
|
||||||
label="[test] en"
|
|
||||||
srclang="en"
|
|
||||||
src="test-webvtt-1.vtt"
|
|
||||||
/>
|
|
||||||
<track
|
|
||||||
id="track2"
|
|
||||||
kind="subtitles"
|
|
||||||
label="[test] fr"
|
|
||||||
srclang="fr"
|
|
||||||
src="test-webvtt-2.vtt"
|
|
||||||
/>
|
|
||||||
<track
|
|
||||||
id="track3"
|
|
||||||
kind="subtitles"
|
|
||||||
label="[test] eo"
|
|
||||||
srclang="eo"
|
|
||||||
src="test-webvtt-3.vtt"
|
|
||||||
/>
|
|
||||||
</video>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function fireEvents() {
|
|
||||||
for (let videoID of ["with-controls"]) {
|
|
||||||
let video = document.getElementById(videoID);
|
|
||||||
let event = new CustomEvent("MozTogglePictureInPicture", { bubbles: true });
|
|
||||||
video.dispatchEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,10 +0,0 @@
|
||||||
WEBVTT
|
|
||||||
|
|
||||||
1
|
|
||||||
00:00:00.000 --> 00:00:01.000
|
|
||||||
track 1 - cue 1
|
|
||||||
|
|
||||||
2
|
|
||||||
00:00:02.000 --> 00:00:03.000
|
|
||||||
- <b>track 1 - cue 2 bold</b>
|
|
||||||
- <i>track 1 - cue 2 italicized<i>
|
|
|
@ -1,10 +0,0 @@
|
||||||
WEBVTT
|
|
||||||
|
|
||||||
1
|
|
||||||
00:00:00.000 --> 00:00:01.000
|
|
||||||
track 2 - cue 1
|
|
||||||
|
|
||||||
2
|
|
||||||
00:00:02.000 --> 00:00:03.000
|
|
||||||
- <b>track 2 - cue 2 bold</b>
|
|
||||||
- <i>track 2 - cue 2 italicized<i>
|
|
|
@ -1,9 +0,0 @@
|
||||||
WEBVTT
|
|
||||||
|
|
||||||
1
|
|
||||||
00:00:00.000 --> 00:00:01.000
|
|
||||||
track 3 - cue 1
|
|
||||||
|
|
||||||
2
|
|
||||||
00:00:00.000 --> 00:00:01.000
|
|
||||||
track 3 - cue 2
|
|
Загрузка…
Ссылка в новой задаче