зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1654054) for causing mochites failures on browser_nimbusMessageFirstTimePip.js CLOSED TREE
Backed out changeset 164e5a97cc41 (bug 1654054) Backed out changeset dde97d800713 (bug 1654054)
This commit is contained in:
Родитель
e0100e2b76
Коммит
9f7f5dc7c8
|
@ -466,15 +466,6 @@ async function compareFiles(src1, src2, options = {}) {
|
|||
iframeElement.addEventListener("load", resolve, { capture: true, once: true });
|
||||
iframeElement.setAttribute("src", new URL(src1, BASE).href);
|
||||
});
|
||||
let mediaElements = iframeElement.contentDocument.querySelectorAll(
|
||||
"audio, video"
|
||||
);
|
||||
for (let mediaElement of mediaElements) {
|
||||
let { widget } = SpecialPowers.wrap(iframeElement.contentWindow)
|
||||
.windowGlobalChild.getActor("UAWidgets")
|
||||
.widgets.get(mediaElement);
|
||||
await widget.impl.Utils.l10n.translateRoots();
|
||||
}
|
||||
|
||||
if (messagePromise) {
|
||||
info("awaiting for message to arrive");
|
||||
|
@ -489,15 +480,6 @@ async function compareFiles(src1, src2, options = {}) {
|
|||
iframeElement.addEventListener("load", resolve, { capture: true, once: true });
|
||||
iframeElement.setAttribute("src", new URL(src2, BASE).href);
|
||||
});
|
||||
mediaElements = iframeElement.contentDocument.querySelectorAll(
|
||||
"audio, video"
|
||||
);
|
||||
for (let mediaElement of mediaElements) {
|
||||
let { widget } = SpecialPowers.wrap(iframeElement.contentWindow)
|
||||
.windowGlobalChild.getActor("UAWidgets")
|
||||
.widgets.get(mediaElement);
|
||||
await widget.impl.Utils.l10n.translateRoots();
|
||||
}
|
||||
|
||||
await printpreview(options.ref || options);
|
||||
drawPrintPreviewWindow(ctx2);
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
# Any copyright is dedicated to the Public Domain.
|
||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
from __future__ import absolute_import
|
||||
import fluent.syntax.ast as FTL
|
||||
from fluent.migrate.helpers import transforms_from, TERM_REFERENCE, VARIABLE_REFERENCE
|
||||
from fluent.migrate import REPLACE, COPY
|
||||
|
||||
|
||||
def migrate(ctx):
|
||||
"""Bug 1654054 - Port videocontrols to Fluent, part {index}."""
|
||||
|
||||
source = "toolkit/chrome/global/videocontrols.dtd"
|
||||
target = "toolkit/toolkit/global/videocontrols.ftl"
|
||||
ctx.add_transforms(
|
||||
target,
|
||||
target,
|
||||
transforms_from(
|
||||
"""
|
||||
videocontrols-play-button =
|
||||
.aria-label = { COPY(from_path, "playButton.playLabel") }
|
||||
|
||||
videocontrols-pause-button =
|
||||
.aria-label = { COPY(from_path, "playButton.pauseLabel") }
|
||||
|
||||
videocontrols-mute-button =
|
||||
.aria-label = { COPY(from_path, "muteButton.muteLabel") }
|
||||
|
||||
videocontrols-unmute-button =
|
||||
.aria-label = { COPY(from_path, "muteButton.unmuteLabel") }
|
||||
|
||||
videocontrols-enterfullscreen-button =
|
||||
.aria-label = { COPY(from_path, "fullscreenButton.enterfullscreenlabel") }
|
||||
|
||||
videocontrols-exitfullscreen-button =
|
||||
.aria-label = { COPY(from_path, "fullscreenButton.exitfullscreenlabel") }
|
||||
|
||||
videocontrols-casting-button-label =
|
||||
.aria-label = { COPY(from_path, "castingButton.castingLabel") }
|
||||
|
||||
videocontrols-closed-caption-off =
|
||||
.offlabel = { COPY(from_path, "closedCaption.off") }
|
||||
|
||||
videocontrols-picture-in-picture-label = { COPY(from_path, "pictureInPicture.label") }
|
||||
|
||||
videocontrols-picture-in-picture-toggle-label = { COPY(from_path, "pictureInPictureToggle.label") }
|
||||
""",
|
||||
from_path=source,
|
||||
),
|
||||
)
|
||||
|
||||
ctx.add_transforms(
|
||||
target,
|
||||
target,
|
||||
[
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("videocontrols-picture-in-picture-explainer"),
|
||||
value=REPLACE(
|
||||
source,
|
||||
"pictureInPictureExplainer",
|
||||
{
|
||||
"&brandShortName;": TERM_REFERENCE("brand-short-name"),
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
ctx.add_transforms(
|
||||
target,
|
||||
target,
|
||||
transforms_from(
|
||||
"""
|
||||
videocontrols-error-aborted = { COPY(from_path, "error.aborted") }
|
||||
|
||||
videocontrols-error-network = { COPY(from_path, "error.network") }
|
||||
|
||||
videocontrols-error-decode = { COPY(from_path, "error.decode") }
|
||||
|
||||
videocontrols-error-src-not-supported = { COPY(from_path, "error.srcNotSupported") }
|
||||
|
||||
videocontrols-error-no-source = { COPY(from_path, "error.noSource2") }
|
||||
|
||||
videocontrols-error-generic = { COPY(from_path, "error.generic") }
|
||||
|
||||
videocontrols-status-picture-in-picture = { COPY(from_path, "status.pictureInPicture") }
|
||||
""",
|
||||
from_path=source,
|
||||
),
|
||||
)
|
||||
|
||||
ctx.add_transforms(
|
||||
target,
|
||||
target,
|
||||
[
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("videocontrols-position-and-duration-labels"),
|
||||
value=REPLACE(
|
||||
source,
|
||||
"positionAndDuration.nameFormat",
|
||||
{
|
||||
"<span>": FTL.TextElement(
|
||||
'<span data-l10n-name="position-duration-format">'
|
||||
),
|
||||
"#1": VARIABLE_REFERENCE("position"),
|
||||
"#2": VARIABLE_REFERENCE("duration"),
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
|
@ -20,17 +20,13 @@
|
|||
const testCases = [];
|
||||
|
||||
function testUI(video) {
|
||||
const clickToPlay = getElementWithinVideo(video, "clickToPlay");
|
||||
ok(!!clickToPlay.getAttribute("aria-label"), "clickToPlay has aria-label attribute");
|
||||
const clickToPlay = getElementWithinVideo(video, "clickToPlay");
|
||||
ok(!!clickToPlay.getAttribute("aria-label"), "clickToPlay has aria-label attribute");
|
||||
};
|
||||
|
||||
videoElems.forEach(video => {
|
||||
testCases.push(() => new Promise(resolve => {
|
||||
SimpleTest.executeSoon(async () => {
|
||||
const { widget } = SpecialPowers.wrap(window)
|
||||
.windowGlobalChild.getActor("UAWidgets")
|
||||
.widgets.get(video);
|
||||
await widget.impl.Utils.l10n.translateRoots();
|
||||
SimpleTest.executeSoon(() => {
|
||||
testUI(video);
|
||||
resolve();
|
||||
});
|
||||
|
|
|
@ -28,15 +28,7 @@ RemoteCanvas.prototype.load = function(callback) {
|
|||
"suspend",
|
||||
function(aEvent) {
|
||||
setTimeout(function() {
|
||||
let mediaElement = iframe.contentDocument.querySelector(
|
||||
"audio, video"
|
||||
);
|
||||
const { widget } = SpecialPowers.wrap(iframe.contentWindow)
|
||||
.windowGlobalChild.getActor("UAWidgets")
|
||||
.widgets.get(mediaElement);
|
||||
widget.impl.Utils.l10n.translateRoots().then(() => {
|
||||
me.remotePageLoaded(callback);
|
||||
});
|
||||
me.remotePageLoaded(callback);
|
||||
}, 0);
|
||||
},
|
||||
{ once: true }
|
||||
|
|
|
@ -264,7 +264,6 @@ this.VideoControlsImplWidget = class {
|
|||
fullscreenButton: null,
|
||||
layoutControls: null,
|
||||
isShowingPictureInPictureMessage: false,
|
||||
l10n: this.l10n,
|
||||
|
||||
textTracksCount: 0,
|
||||
videoEvents: [
|
||||
|
@ -474,12 +473,101 @@ this.VideoControlsImplWidget = class {
|
|||
this.clickToPlay,
|
||||
];
|
||||
|
||||
let throwOnGet = {
|
||||
get() {
|
||||
throw new Error("Please don't trigger reflow. See bug 1493525.");
|
||||
},
|
||||
};
|
||||
|
||||
for (let control of adjustableControls) {
|
||||
if (!control) {
|
||||
break;
|
||||
}
|
||||
|
||||
this.defineControlProperties(control);
|
||||
Object.defineProperties(control, {
|
||||
// We should directly access CSSOM to get pre-defined style instead of
|
||||
// retrieving computed dimensions from layout.
|
||||
minWidth: {
|
||||
get: () => {
|
||||
let controlId = control.id;
|
||||
let propertyName = `--${controlId}-width`;
|
||||
if (control.modifier) {
|
||||
propertyName += "-" + control.modifier;
|
||||
}
|
||||
let preDefinedSize = this.controlBarComputedStyles.getPropertyValue(
|
||||
propertyName
|
||||
);
|
||||
|
||||
// The stylesheet from <link> might not be loaded if the
|
||||
// element was inserted into a hidden iframe.
|
||||
// We can safely return 0 here for now, given that the controls
|
||||
// will be resized again, by the resizevideocontrols event,
|
||||
// from nsVideoFrame, when the element is visible.
|
||||
if (!preDefinedSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return parseInt(preDefinedSize, 10);
|
||||
},
|
||||
},
|
||||
offsetLeft: throwOnGet,
|
||||
offsetTop: throwOnGet,
|
||||
offsetWidth: throwOnGet,
|
||||
offsetHeight: throwOnGet,
|
||||
offsetParent: throwOnGet,
|
||||
clientLeft: throwOnGet,
|
||||
clientTop: throwOnGet,
|
||||
clientWidth: throwOnGet,
|
||||
clientHeight: throwOnGet,
|
||||
getClientRects: throwOnGet,
|
||||
getBoundingClientRect: throwOnGet,
|
||||
isAdjustableControl: {
|
||||
value: true,
|
||||
},
|
||||
modifier: {
|
||||
value: "",
|
||||
writable: true,
|
||||
},
|
||||
isWanted: {
|
||||
value: true,
|
||||
writable: true,
|
||||
},
|
||||
hidden: {
|
||||
set: v => {
|
||||
control._isHiddenExplicitly = v;
|
||||
control._updateHiddenAttribute();
|
||||
},
|
||||
get: () => {
|
||||
return (
|
||||
control.hasAttribute("hidden") ||
|
||||
control.classList.contains("fadeout")
|
||||
);
|
||||
},
|
||||
},
|
||||
hiddenByAdjustment: {
|
||||
set: v => {
|
||||
control._isHiddenByAdjustment = v;
|
||||
control._updateHiddenAttribute();
|
||||
},
|
||||
get: () => control._isHiddenByAdjustment,
|
||||
},
|
||||
_isHiddenByAdjustment: {
|
||||
value: false,
|
||||
writable: true,
|
||||
},
|
||||
_isHiddenExplicitly: {
|
||||
value: false,
|
||||
writable: true,
|
||||
},
|
||||
_updateHiddenAttribute: {
|
||||
value: () => {
|
||||
control.toggleAttribute(
|
||||
"hidden",
|
||||
control._isHiddenExplicitly || control._isHiddenByAdjustment
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
this.adjustControlSize();
|
||||
|
||||
|
@ -489,98 +577,6 @@ this.VideoControlsImplWidget = class {
|
|||
this.updateVolumeControls();
|
||||
},
|
||||
|
||||
defineControlProperties(control) {
|
||||
let throwOnGet = {
|
||||
get() {
|
||||
throw new Error("Please don't trigger reflow. See bug 1493525.");
|
||||
},
|
||||
};
|
||||
Object.defineProperties(control, {
|
||||
// We should directly access CSSOM to get pre-defined style instead of
|
||||
// retrieving computed dimensions from layout.
|
||||
minWidth: {
|
||||
get: () => {
|
||||
let controlId = control.id;
|
||||
let propertyName = `--${controlId}-width`;
|
||||
if (control.modifier) {
|
||||
propertyName += "-" + control.modifier;
|
||||
}
|
||||
let preDefinedSize = this.controlBarComputedStyles.getPropertyValue(
|
||||
propertyName
|
||||
);
|
||||
|
||||
// The stylesheet from <link> might not be loaded if the
|
||||
// element was inserted into a hidden iframe.
|
||||
// We can safely return 0 here for now, given that the controls
|
||||
// will be resized again, by the resizevideocontrols event,
|
||||
// from nsVideoFrame, when the element is visible.
|
||||
if (!preDefinedSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return parseInt(preDefinedSize, 10);
|
||||
},
|
||||
},
|
||||
offsetLeft: throwOnGet,
|
||||
offsetTop: throwOnGet,
|
||||
offsetWidth: throwOnGet,
|
||||
offsetHeight: throwOnGet,
|
||||
offsetParent: throwOnGet,
|
||||
clientLeft: throwOnGet,
|
||||
clientTop: throwOnGet,
|
||||
clientWidth: throwOnGet,
|
||||
clientHeight: throwOnGet,
|
||||
getClientRects: throwOnGet,
|
||||
getBoundingClientRect: throwOnGet,
|
||||
isAdjustableControl: {
|
||||
value: true,
|
||||
},
|
||||
modifier: {
|
||||
value: "",
|
||||
writable: true,
|
||||
},
|
||||
isWanted: {
|
||||
value: true,
|
||||
writable: true,
|
||||
},
|
||||
hidden: {
|
||||
set: v => {
|
||||
control._isHiddenExplicitly = v;
|
||||
control._updateHiddenAttribute();
|
||||
},
|
||||
get: () => {
|
||||
return (
|
||||
control.hasAttribute("hidden") ||
|
||||
control.classList.contains("fadeout")
|
||||
);
|
||||
},
|
||||
},
|
||||
hiddenByAdjustment: {
|
||||
set: v => {
|
||||
control._isHiddenByAdjustment = v;
|
||||
control._updateHiddenAttribute();
|
||||
},
|
||||
get: () => control._isHiddenByAdjustment,
|
||||
},
|
||||
_isHiddenByAdjustment: {
|
||||
value: false,
|
||||
writable: true,
|
||||
},
|
||||
_isHiddenExplicitly: {
|
||||
value: false,
|
||||
writable: true,
|
||||
},
|
||||
_updateHiddenAttribute: {
|
||||
value: () => {
|
||||
control.toggleAttribute(
|
||||
"hidden",
|
||||
control._isHiddenExplicitly || control._isHiddenByAdjustment
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
updatePictureInPictureToggleDisplay() {
|
||||
if (this.isAudioOnly) {
|
||||
this.pictureInPictureToggle.hidden = true;
|
||||
|
@ -1161,16 +1157,35 @@ this.VideoControlsImplWidget = class {
|
|||
},
|
||||
|
||||
initPositionDurationBox() {
|
||||
const positionTextNode = Array.prototype.find.call(
|
||||
this.positionDurationBox.childNodes,
|
||||
n => !!~n.textContent.search("#1")
|
||||
);
|
||||
const durationSpan = this.durationSpan;
|
||||
const durationFormat = durationSpan.textContent;
|
||||
const positionFormat = positionTextNode.textContent;
|
||||
|
||||
durationSpan.classList.add("duration");
|
||||
durationSpan.setAttribute("role", "none");
|
||||
durationSpan.id = "durationSpan";
|
||||
this.l10n.setAttributes(
|
||||
this.positionDurationBox,
|
||||
"videocontrols-position-and-duration-labels",
|
||||
{ position: "", duration: "" }
|
||||
);
|
||||
|
||||
Object.defineProperties(this.positionDurationBox, {
|
||||
durationSpan: {
|
||||
value: durationSpan,
|
||||
},
|
||||
position: {
|
||||
set: v => {
|
||||
positionTextNode.textContent = positionFormat.replace("#1", v);
|
||||
},
|
||||
},
|
||||
duration: {
|
||||
set: v => {
|
||||
durationSpan.textContent = v
|
||||
? durationFormat.replace("#2", v)
|
||||
: "";
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
showDuration(duration) {
|
||||
|
@ -1187,14 +1202,6 @@ this.VideoControlsImplWidget = class {
|
|||
// Format the duration as "h:mm:ss" or "m:ss"
|
||||
let timeString = isInfinite ? "" : this.formatTime(duration);
|
||||
this.positionDurationBox.duration = timeString;
|
||||
this.l10n.setAttributes(
|
||||
this.positionDurationBox,
|
||||
"videocontrols-position-and-duration-labels",
|
||||
{
|
||||
position: this.positionDurationBox.position,
|
||||
duration: timeString,
|
||||
}
|
||||
);
|
||||
|
||||
if (this.showHours) {
|
||||
this.positionDurationBox.modifier = "long";
|
||||
|
@ -1272,38 +1279,10 @@ this.VideoControlsImplWidget = class {
|
|||
|
||||
this.scrubber.value = currentTime;
|
||||
this.positionDurationBox.position = positionTime;
|
||||
|
||||
this.l10n.setAttributes(
|
||||
this.positionDurationBox,
|
||||
"videocontrols-position-and-duration-labels",
|
||||
{
|
||||
position: positionTime,
|
||||
duration: this.positionDurationBox.duration,
|
||||
}
|
||||
this.scrubber.setAttribute(
|
||||
"aria-valuetext",
|
||||
this.positionDurationBox.textContent.trim()
|
||||
);
|
||||
|
||||
// We use .formatValueSync here because .setAttribute doesn't update
|
||||
// the DOM fast enough to use this.positionDurationBox.textContent and
|
||||
// if we set the innterHTML on the positionDurationBox then we lose
|
||||
// reference to the durationSpan element so it is easier to use
|
||||
// .formatValueSync to just update the string for the aria-valuetext
|
||||
let positionDurationMarkup = this.l10n.formatValueSync(
|
||||
"videocontrols-position-and-duration-labels",
|
||||
{
|
||||
position: positionTime,
|
||||
duration: this.positionDurationBox.duration,
|
||||
}
|
||||
);
|
||||
|
||||
// It's possible that the string we get has markup to overlay into the
|
||||
// DOM. We only want the raw text so we use DOMParser to strip any tags
|
||||
let parser = new this.window.DOMParser();
|
||||
let positionDurationString = parser.parseFromString(
|
||||
positionDurationMarkup,
|
||||
"text/html"
|
||||
).body.textContent;
|
||||
|
||||
this.scrubber.setAttribute("aria-valuetext", positionDurationString);
|
||||
this.updateScrubberProgress();
|
||||
},
|
||||
|
||||
|
@ -1719,10 +1698,11 @@ this.VideoControlsImplWidget = class {
|
|||
this.controlBar.removeAttribute("fullscreen-unavailable");
|
||||
this.adjustControlSize();
|
||||
|
||||
var id = this.isVideoInFullScreen
|
||||
? "videocontrols-exitfullscreen-button"
|
||||
: "videocontrols-enterfullscreen-button";
|
||||
this.l10n.setAttributes(this.fullscreenButton, id);
|
||||
var attrName = this.isVideoInFullScreen
|
||||
? "exitfullscreenlabel"
|
||||
: "enterfullscreenlabel";
|
||||
var value = this.fullscreenButton.getAttribute(attrName);
|
||||
this.fullscreenButton.setAttribute("aria-label", value);
|
||||
|
||||
if (this.isVideoInFullScreen) {
|
||||
this.fullscreenButton.setAttribute("fullscreened", "true");
|
||||
|
@ -1823,11 +1803,10 @@ this.VideoControlsImplWidget = class {
|
|||
this.playButton.removeAttribute("paused");
|
||||
}
|
||||
|
||||
var id = aPaused
|
||||
? "videocontrols-play-button"
|
||||
: "videocontrols-pause-button";
|
||||
this.l10n.setAttributes(this.playButton, id);
|
||||
this.l10n.setAttributes(this.clickToPlay, id);
|
||||
var attrName = aPaused ? "playlabel" : "pauselabel";
|
||||
var value = this.playButton.getAttribute(attrName);
|
||||
this.playButton.setAttribute("aria-label", value);
|
||||
this.clickToPlay.setAttribute("aria-label", value);
|
||||
},
|
||||
|
||||
get isEffectivelyMuted() {
|
||||
|
@ -1843,10 +1822,9 @@ this.VideoControlsImplWidget = class {
|
|||
this.muteButton.removeAttribute("muted");
|
||||
}
|
||||
|
||||
var id = muted
|
||||
? "videocontrols-unmute-button"
|
||||
: "videocontrols-mute-button";
|
||||
this.l10n.setAttributes(this.muteButton, id);
|
||||
var attrName = muted ? "unmutelabel" : "mutelabel";
|
||||
var value = this.muteButton.getAttribute(attrName);
|
||||
this.muteButton.setAttribute("aria-label", value);
|
||||
},
|
||||
|
||||
keyboardVolumeDecrease() {
|
||||
|
@ -2398,18 +2376,7 @@ this.VideoControlsImplWidget = class {
|
|||
let widthUsed = minControlBarPaddingWidth;
|
||||
let preventAppendControl = false;
|
||||
|
||||
for (let [index, control] of this.prioritizedControls.entries()) {
|
||||
// The "durationSpan" element is disconnected from the document during l10n so
|
||||
// we check if our reference to "durationSpan" is the connected one and if not we
|
||||
// replace it with the correct one
|
||||
if (control.id === "durationSpan" && !control.isConnected) {
|
||||
const durationSpan = this.durationSpan;
|
||||
if (durationSpan) {
|
||||
this.defineControlProperties(durationSpan);
|
||||
this.prioritizedControls[index] = durationSpan;
|
||||
control = durationSpan;
|
||||
}
|
||||
}
|
||||
for (let control of this.prioritizedControls) {
|
||||
if (!control.isWanted) {
|
||||
control.hiddenByAdjustment = true;
|
||||
continue;
|
||||
|
@ -2500,14 +2467,6 @@ this.VideoControlsImplWidget = class {
|
|||
);
|
||||
},
|
||||
|
||||
get positionDurationBox() {
|
||||
return this.shadowRoot.getElementById("positionDurationBox");
|
||||
},
|
||||
|
||||
get durationSpan() {
|
||||
return this.positionDurationBox?.getElementsByTagName("span")[0];
|
||||
},
|
||||
|
||||
init(shadowRoot, prefs) {
|
||||
this.shadowRoot = shadowRoot;
|
||||
this.video = this.installReflowCallValidator(shadowRoot.host);
|
||||
|
@ -2538,6 +2497,9 @@ this.VideoControlsImplWidget = class {
|
|||
this.scrubber = this.shadowRoot.getElementById("scrubber");
|
||||
this.durationLabel = this.shadowRoot.getElementById("durationLabel");
|
||||
this.positionLabel = this.shadowRoot.getElementById("positionLabel");
|
||||
this.positionDurationBox = this.shadowRoot.getElementById(
|
||||
"positionDurationBox"
|
||||
);
|
||||
this.statusOverlay = this.shadowRoot.getElementById("statusOverlay");
|
||||
this.controlsOverlay = this.shadowRoot.getElementById(
|
||||
"controlsOverlay"
|
||||
|
@ -2562,6 +2524,12 @@ this.VideoControlsImplWidget = class {
|
|||
"pictureInPictureToggle"
|
||||
);
|
||||
|
||||
if (this.positionDurationBox) {
|
||||
this.durationSpan = this.positionDurationBox.getElementsByTagName(
|
||||
"span"
|
||||
)[0];
|
||||
}
|
||||
|
||||
let isMobile = this.window.navigator.appVersion.includes("Android");
|
||||
if (isMobile) {
|
||||
this.controlsContainer.classList.add("mobile");
|
||||
|
@ -2832,30 +2800,35 @@ this.VideoControlsImplWidget = class {
|
|||
* Remove it when migrate to Fluent.
|
||||
*/
|
||||
const parser = new this.window.DOMParser();
|
||||
parser.forceEnableDTD();
|
||||
let parserDoc = parser.parseFromString(
|
||||
`<div class="videocontrols" xmlns="http://www.w3.org/1999/xhtml" role="none">
|
||||
`<!DOCTYPE bindings [
|
||||
<!ENTITY % videocontrolsDTD SYSTEM "chrome://global/locale/videocontrols.dtd">
|
||||
%videocontrolsDTD;
|
||||
]>
|
||||
<div class="videocontrols" xmlns="http://www.w3.org/1999/xhtml" role="none">
|
||||
<link rel="stylesheet" href="chrome://global/skin/media/videocontrols.css" />
|
||||
|
||||
<div id="controlsContainer" class="controlsContainer" role="none">
|
||||
<div id="statusOverlay" class="statusOverlay stackItem" hidden="true">
|
||||
<div id="statusIcon" class="statusIcon"></div>
|
||||
<bdi class="statusLabel" id="errorAborted" data-l10n-id="videocontrols-error-aborted"></bdi>
|
||||
<bdi class="statusLabel" id="errorNetwork" data-l10n-id="videocontrols-error-network"></bdi>
|
||||
<bdi class="statusLabel" id="errorDecode" data-l10n-id="videocontrols-error-decode"></bdi>
|
||||
<bdi class="statusLabel" id="errorSrcNotSupported" data-l10n-id="videocontrols-error-src-not-supported"></bdi>
|
||||
<bdi class="statusLabel" id="errorNoSource" data-l10n-id="videocontrols-error-no-source"></bdi>
|
||||
<bdi class="statusLabel" id="errorGeneric"> data-l10n-id="videocontrols-error-generic"></bdi>
|
||||
<bdi class="statusLabel" id="errorAborted">&error.aborted;</bdi>
|
||||
<bdi class="statusLabel" id="errorNetwork">&error.network;</bdi>
|
||||
<bdi class="statusLabel" id="errorDecode">&error.decode;</bdi>
|
||||
<bdi class="statusLabel" id="errorSrcNotSupported">&error.srcNotSupported;</bdi>
|
||||
<bdi class="statusLabel" id="errorNoSource">&error.noSource2;</bdi>
|
||||
<bdi class="statusLabel" id="errorGeneric">&error.generic;</bdi>
|
||||
</div>
|
||||
|
||||
<div id="pictureInPictureOverlay" class="pictureInPictureOverlay stackItem" status="pictureInPicture" hidden="true">
|
||||
<div class="statusIcon" type="pictureInPicture"></div>
|
||||
<bdi class="statusLabel" id="pictureInPicture" data-l10n-id="videocontrols-status-picture-in-picture"></bdi>
|
||||
<bdi class="statusLabel" id="pictureInPicture">&status.pictureInPicture;</bdi>
|
||||
</div>
|
||||
|
||||
<div id="controlsOverlay" class="controlsOverlay stackItem" role="none">
|
||||
<div class="controlsSpacerStack">
|
||||
<div id="controlsSpacer" class="controlsSpacer stackItem" role="none"></div>
|
||||
<button id="clickToPlay" class="clickToPlay" hidden="true"></button>
|
||||
<button id="clickToPlay" class="clickToPlay" aria-label="&playButton.playLabel;" hidden="true"></button>
|
||||
</div>
|
||||
|
||||
<button id="pictureInPictureToggle" class="pip-wrapper" position="left" hidden="true">
|
||||
|
@ -2863,9 +2836,11 @@ this.VideoControlsImplWidget = class {
|
|||
<div class="pip-expanded clickable">
|
||||
<span class="pip-icon-label clickable">
|
||||
<span class="pip-icon"></span>
|
||||
<span class="pip-label" data-l10n-id="videocontrols-picture-in-picture-toggle-label"></span>
|
||||
<span class="pip-label">&pictureInPictureToggle.label;</span>
|
||||
</span>
|
||||
<div class="pip-explainer clickable" data-l10n-id="videocontrols-picture-in-picture-explainer"></div>
|
||||
<div class="pip-explainer clickable">
|
||||
&pictureInPictureExplainer;
|
||||
</div>
|
||||
</div>
|
||||
<div class="pip-icon clickable"></div>
|
||||
</button>
|
||||
|
@ -2873,6 +2848,8 @@ this.VideoControlsImplWidget = class {
|
|||
<div id="controlBar" class="controlBar" role="none" hidden="true">
|
||||
<button id="playButton"
|
||||
class="button playButton"
|
||||
playlabel="&playButton.playLabel;"
|
||||
pauselabel="&playButton.pauseLabel;"
|
||||
tabindex="-1"/>
|
||||
<div id="scrubberStack" class="scrubberStack progressContainer" role="none">
|
||||
<div class="progressBackgroundBar stackItem" role="none">
|
||||
|
@ -2890,36 +2867,39 @@ this.VideoControlsImplWidget = class {
|
|||
<bdi id="positionLabel" class="positionLabel" role="presentation"></bdi>
|
||||
<bdi id="durationLabel" class="durationLabel" role="presentation"></bdi>
|
||||
<bdi id="positionDurationBox" class="positionDurationBox" aria-hidden="true">
|
||||
<span data-l10n-name="position-duration-format"></span>
|
||||
&positionAndDuration.nameFormat;
|
||||
</bdi>
|
||||
<div id="controlBarSpacer" class="controlBarSpacer" hidden="true" role="none"></div>
|
||||
<button id="muteButton"
|
||||
class="button muteButton"
|
||||
mutelabel="&muteButton.muteLabel;"
|
||||
unmutelabel="&muteButton.unmuteLabel;"
|
||||
tabindex="-1"/>
|
||||
<div id="volumeStack" class="volumeStack progressContainer" role="none">
|
||||
<input type="range" id="volumeControl" class="volumeControl" min="0" max="100" step="1" tabindex="-1"
|
||||
data-l10n-id="videocontrols-volume-control"/>
|
||||
</div>
|
||||
<button id="castingButton" class="button castingButton"
|
||||
data-l10n-id="videocontrols-casting-button-label"/>
|
||||
aria-label="&castingButton.castingLabel;"/>
|
||||
<button id="closedCaptionButton" class="button closedCaptionButton" aria-controls="textTrackList"
|
||||
aria-haspopup="menu" aria-expanded="false" data-l10n-id="videocontrols-closed-caption-button"/>
|
||||
<div id="textTrackListContainer" class="textTrackListContainer" hidden="true" role="presentation">
|
||||
<div id="textTrackList" role="menu" class="textTrackList"
|
||||
data-l10n-id="videocontrols-closed-caption-off" data-l10n-attrs="offlabel"/>
|
||||
<div id="textTrackList" role="menu" class="textTrackList" offlabel="&closedCaption.off;"
|
||||
data-l10n-id="videocontrols-closed-caption-button"/>
|
||||
</div>
|
||||
<button id="fullscreenButton"
|
||||
class="button fullscreenButton"/>
|
||||
class="button fullscreenButton"
|
||||
enterfullscreenlabel="&fullscreenButton.enterfullscreenlabel;"
|
||||
exitfullscreenlabel="&fullscreenButton.exitfullscreenlabel;"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`,
|
||||
"application/xml"
|
||||
);
|
||||
this.l10n = new this.window.DOMLocalization(
|
||||
["branding/brand.ftl", "toolkit/global/videocontrols.ftl"],
|
||||
true
|
||||
);
|
||||
this.l10n = new this.window.DOMLocalization([
|
||||
"toolkit/global/videocontrols.ftl",
|
||||
]);
|
||||
this.l10n.connectRoot(this.shadowRoot);
|
||||
if (this.prefs["media.videocontrols.keyboard-tab-to-all-controls"]) {
|
||||
// Make all of the individual controls tabbable.
|
||||
|
@ -2934,7 +2914,6 @@ this.VideoControlsImplWidget = class {
|
|||
parserDoc.documentElement,
|
||||
true
|
||||
);
|
||||
this.l10n.translateRoots();
|
||||
}
|
||||
|
||||
elementStateMatches(element) {
|
||||
|
@ -3123,8 +3102,13 @@ this.NoControlsMobileImplWidget = class {
|
|||
* Remove it when migrate to Fluent.
|
||||
*/
|
||||
const parser = new this.window.DOMParser();
|
||||
parser.forceEnableDTD();
|
||||
let parserDoc = parser.parseFromString(
|
||||
`<div class="videocontrols" xmlns="http://www.w3.org/1999/xhtml" role="none">
|
||||
`<!DOCTYPE bindings [
|
||||
<!ENTITY % videocontrolsDTD SYSTEM "chrome://global/locale/videocontrols.dtd">
|
||||
%videocontrolsDTD;
|
||||
]>
|
||||
<div class="videocontrols" xmlns="http://www.w3.org/1999/xhtml" role="none">
|
||||
<link rel="stylesheet" href="chrome://global/skin/media/videocontrols.css" />
|
||||
<div id="controlsContainer" class="controlsContainer" role="none" hidden="true">
|
||||
<div class="controlsOverlay stackItem">
|
||||
|
@ -3175,13 +3159,18 @@ this.NoControlsPictureInPictureImplWidget = class {
|
|||
* Remove it when migrate to Fluent.
|
||||
*/
|
||||
const parser = new this.window.DOMParser();
|
||||
parser.forceEnableDTD();
|
||||
let parserDoc = parser.parseFromString(
|
||||
`<div class="videocontrols" xmlns="http://www.w3.org/1999/xhtml" role="none">
|
||||
`<!DOCTYPE bindings [
|
||||
<!ENTITY % videocontrolsDTD SYSTEM "chrome://global/locale/videocontrols.dtd">
|
||||
%videocontrolsDTD;
|
||||
]>
|
||||
<div class="videocontrols" xmlns="http://www.w3.org/1999/xhtml" role="none">
|
||||
<link rel="stylesheet" href="chrome://global/skin/media/videocontrols.css" />
|
||||
<div id="controlsContainer" class="controlsContainer" role="none">
|
||||
<div class="pictureInPictureOverlay stackItem" status="pictureInPicture">
|
||||
<div id="statusIcon" class="statusIcon" type="pictureInPicture"></div>
|
||||
<bdi class="statusLabel" id="pictureInPicture" data-l10n-id="videocontrols-status-picture-in-picture"></bdi>
|
||||
<bdi class="statusLabel" id="pictureInPicture">&status.pictureInPicture;</bdi>
|
||||
</div>
|
||||
<div class="controlsOverlay stackItem"></div>
|
||||
</div>
|
||||
|
@ -3193,12 +3182,6 @@ this.NoControlsPictureInPictureImplWidget = class {
|
|||
parserDoc.documentElement,
|
||||
true
|
||||
);
|
||||
this.l10n = new this.window.DOMLocalization([
|
||||
"branding/brand.ftl",
|
||||
"toolkit/global/videocontrols.ftl",
|
||||
]);
|
||||
this.l10n.connectRoot(this.shadowRoot);
|
||||
this.l10n.translateRoots();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -3358,8 +3341,13 @@ this.NoControlsDesktopImplWidget = class {
|
|||
* Remove it when migrate to Fluent.
|
||||
*/
|
||||
const parser = new this.window.DOMParser();
|
||||
parser.forceEnableDTD();
|
||||
let parserDoc = parser.parseFromString(
|
||||
`<div class="videocontrols" xmlns="http://www.w3.org/1999/xhtml" role="none">
|
||||
`<!DOCTYPE bindings [
|
||||
<!ENTITY % videocontrolsDTD SYSTEM "chrome://global/locale/videocontrols.dtd">
|
||||
%videocontrolsDTD;
|
||||
]>
|
||||
<div class="videocontrols" xmlns="http://www.w3.org/1999/xhtml" role="none">
|
||||
<link rel="stylesheet" href="chrome://global/skin/media/videocontrols.css" />
|
||||
|
||||
<div id="controlsContainer" class="controlsContainer" role="none">
|
||||
|
@ -3369,9 +3357,11 @@ this.NoControlsDesktopImplWidget = class {
|
|||
<div class="pip-expanded clickable">
|
||||
<span class="pip-icon-label clickable">
|
||||
<span class="pip-icon"></span>
|
||||
<span class="pip-label" data-l10n-id="videocontrols-picture-in-picture-toggle-label"></span>
|
||||
<span class="pip-label">&pictureInPictureToggle.label;</span>
|
||||
</span>
|
||||
<div class="pip-explainer clickable" data-l10n-id="videocontrols-picture-in-picture-explainer"></div>
|
||||
<div class="pip-explainer clickable">
|
||||
&pictureInPictureExplainer;
|
||||
</div>
|
||||
</div>
|
||||
<div class="pip-icon"></div>
|
||||
</button>
|
||||
|
@ -3385,11 +3375,5 @@ this.NoControlsDesktopImplWidget = class {
|
|||
parserDoc.documentElement,
|
||||
true
|
||||
);
|
||||
this.l10n = new this.window.DOMLocalization([
|
||||
"branding/brand.ftl",
|
||||
"toolkit/global/videocontrols.ftl",
|
||||
]);
|
||||
this.l10n.connectRoot(this.shadowRoot);
|
||||
this.l10n.translateRoots();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<!ENTITY % brandDTD
|
||||
SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
%brandDTD;
|
||||
|
||||
<!ENTITY playButton.playLabel "Play">
|
||||
<!ENTITY playButton.pauseLabel "Pause">
|
||||
<!ENTITY muteButton.muteLabel "Mute">
|
||||
<!ENTITY muteButton.unmuteLabel "Unmute">
|
||||
<!ENTITY fullscreenButton.enterfullscreenlabel "Full Screen">
|
||||
<!ENTITY fullscreenButton.exitfullscreenlabel "Exit Full Screen">
|
||||
<!ENTITY castingButton.castingLabel "Cast to Screen">
|
||||
<!ENTITY closedCaption.off "Off">
|
||||
|
||||
<!-- LOCALIZATION NOTE (pictureInPicture.label): This string is used as part of
|
||||
the Picture-in-Picture video toggle button when the mouse is hovering it. -->
|
||||
<!ENTITY pictureInPicture.label "Picture-in-Picture">
|
||||
|
||||
<!-- LOCALIZATION NOTE (pictureInPictureToggle.label): This string is used as the
|
||||
label for a variation of the Picture-in-Picture video toggle button when the mouse is
|
||||
hovering over the video. -->
|
||||
<!ENTITY pictureInPictureToggle.label "Watch in Picture-in-Picture">
|
||||
<!-- LOCALIZATION NOTE (pictureInPictureExplainer): This string is used as part of
|
||||
a variation of the Picture-in-Picture video toggle button. When using this variation,
|
||||
this string appears below the toggle when the mouse hovers the toggle. -->
|
||||
<!ENTITY pictureInPictureExplainer "Play videos in the foreground while you do other things in &brandShortName;">
|
||||
|
||||
<!ENTITY error.aborted "Video loading stopped.">
|
||||
<!ENTITY error.network "Video playback aborted due to a network error.">
|
||||
<!ENTITY error.decode "Video can’t be played because the file is corrupt.">
|
||||
<!ENTITY error.srcNotSupported "Video format or MIME type is not supported.">
|
||||
<!ENTITY error.noSource2 "No video with supported format and MIME type found.">
|
||||
<!ENTITY error.generic "Video playback aborted due to an unknown error.">
|
||||
|
||||
<!ENTITY status.pictureInPicture "This video is playing in Picture-in-Picture mode.">
|
||||
|
||||
<!-- LOCALIZATION NOTE (positionAndDuration.nameFormat): the #1 string is the current
|
||||
media position, and the #2 string is the total duration. For example, when at
|
||||
the 5 minute mark in a 6 hour long video, #1 would be "5:00" and #2 would be
|
||||
"6:00:00", result string would be "5:00 / 6:00:00".
|
||||
Note that #2 is not always available. For example, when at the 5 minute mark in an
|
||||
unknown duration video, #1 would be "5:00" and the string which is surrounded by
|
||||
<span> would be deleted, result string would be "5:00".
|
||||
-->
|
||||
<!ENTITY positionAndDuration.nameFormat "#1<span> / #2</span>">
|
|
@ -12,55 +12,3 @@ videocontrols-volume-control =
|
|||
.aria-label = Volume
|
||||
videocontrols-closed-caption-button =
|
||||
.aria-label = Closed Captions
|
||||
|
||||
videocontrols-play-button =
|
||||
.aria-label = Play
|
||||
videocontrols-pause-button =
|
||||
.aria-label = Pause
|
||||
videocontrols-mute-button =
|
||||
.aria-label = Mute
|
||||
videocontrols-unmute-button =
|
||||
.aria-label = Unmute
|
||||
videocontrols-enterfullscreen-button =
|
||||
.aria-label = Full Screen
|
||||
videocontrols-exitfullscreen-button =
|
||||
.aria-label = Exit Full Screen
|
||||
videocontrols-casting-button-label =
|
||||
.aria-label = Cast to Screen
|
||||
videocontrols-closed-caption-off =
|
||||
.offlabel = Off
|
||||
|
||||
# This string is used as part of the Picture-in-Picture video toggle button when
|
||||
# the mouse is hovering it.
|
||||
videocontrols-picture-in-picture-label = Picture-in-Picture
|
||||
|
||||
# This string is used as the label for a variation of the Picture-in-Picture video
|
||||
# toggle button when the mouse is hovering over the video.
|
||||
videocontrols-picture-in-picture-toggle-label = Watch in Picture-in-Picture
|
||||
|
||||
# This string is used as part of a variation of the Picture-in-Picture video toggle
|
||||
# button. When using this variation, this string appears below the toggle when the
|
||||
# mouse hovers the toggle.
|
||||
videocontrols-picture-in-picture-explainer = Play videos in the foreground while you do other things in { -brand-short-name }
|
||||
|
||||
videocontrols-error-aborted = Video loading stopped.
|
||||
videocontrols-error-network = Video playback aborted due to a network error.
|
||||
videocontrols-error-decode = Video can’t be played because the file is corrupt.
|
||||
videocontrols-error-src-not-supported = Video format or MIME type is not supported.
|
||||
videocontrols-error-no-source = No video with supported format and MIME type found.
|
||||
videocontrols-error-generic = Video playback aborted due to an unknown error.
|
||||
videocontrols-status-picture-in-picture = This video is playing in Picture-in-Picture mode.
|
||||
|
||||
# This message shows the current position and total video duration
|
||||
#
|
||||
# Variables:
|
||||
# $position (String): The current media position
|
||||
# $duration (String): The total video duration
|
||||
#
|
||||
# For example, when at the 5 minute mark in a 6 hour long video,
|
||||
# $position would be "5:00" and $duration would be "6:00:00", result
|
||||
# string would be "5:00 / 6:00:00". Note that $duration is not always
|
||||
# available. For example, when at the 5 minute mark in an unknown
|
||||
# duration video, $position would be "5:00" and the string which is
|
||||
# surrounded by <span> would be deleted, result string would be "5:00".
|
||||
videocontrols-position-and-duration-labels = { $position }<span data-l10n-name="position-duration-format"> / { $duration }</span>
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
locale/@AB_CD@/global/resetProfile.properties (%chrome/global/resetProfile.properties)
|
||||
locale/@AB_CD@/global/dialog.properties (%chrome/global/dialog.properties)
|
||||
locale/@AB_CD@/global/tree.dtd (%chrome/global/tree.dtd)
|
||||
locale/@AB_CD@/global/videocontrols.dtd (%chrome/global/videocontrols.dtd)
|
||||
locale/@AB_CD@/global/viewSource.properties (%chrome/global/viewSource.properties)
|
||||
locale/@AB_CD@/global/wizard.properties (%chrome/global/wizard.properties)
|
||||
% locale global-platform @AB_CD@ %locale/@AB_CD@/global-platform/unix/ os=LikeUnix os=Android
|
||||
|
|
Загрузка…
Ссылка в новой задаче