Backed out 6 changesets (bug 1531101) for Mochitest failure in toolkit/content/tests/widgets/test_videocontrols_error.html. CLOSED TREE

Backed out changeset 10e9bbf2d1df (bug 1531101)
Backed out changeset 44d96bcc51f7 (bug 1531101)
Backed out changeset 4a4b44c3481a (bug 1531101)
Backed out changeset 12bcda2d76db (bug 1531101)
Backed out changeset 5887b55233c2 (bug 1531101)
Backed out changeset 13a0c61ed4fc (bug 1531101)
This commit is contained in:
Dorel Luca 2019-03-12 02:04:54 +02:00
parent 716250e4da
commit 8d4d6ee416
9 changed files with 39 additions and 185 deletions

View File

@ -481,19 +481,9 @@ void HTMLVideoElement::CloneElementVisually(HTMLVideoElement& aTargetVideo,
aTargetVideo.SetMediaInfo(mMediaInfo);
if (IsInComposedDoc()) {
NotifyUAWidgetSetupOrChange();
}
MaybeBeginCloningVisually();
}
void HTMLVideoElement::StopCloningElementVisually() {
if (mVisualCloneTarget) {
EndCloningVisually();
}
}
void HTMLVideoElement::MaybeBeginCloningVisually() {
if (!mVisualCloneTarget) {
return;
@ -536,10 +526,6 @@ void HTMLVideoElement::EndCloningVisually() {
Unused << mVisualCloneTarget->SetVisualCloneSource(nullptr);
Unused << SetVisualCloneTarget(nullptr);
if (IsInComposedDoc()) {
NotifyUAWidgetSetupOrChange();
}
}
} // namespace dom

View File

@ -139,10 +139,6 @@ class HTMLVideoElement final : public HTMLMediaElement {
void CloneElementVisually(HTMLVideoElement& aTarget, ErrorResult& rv);
void StopCloningElementVisually();
bool IsCloningElementVisually() const { return !!mVisualCloneTarget; }
protected:
virtual ~HTMLVideoElement();

View File

@ -59,16 +59,6 @@ partial interface HTMLVideoElement {
// both <video> elements are not attached to a DOM tree.
[Throws, Func="IsChromeOrXBLOrUAWidget"]
void cloneElementVisually(HTMLVideoElement target);
// Stops a <video> from cloning visually. Does nothing if the <video>
// wasn't cloning in the first place.
[Func="IsChromeOrXBLOrUAWidget"]
void stopCloningElementVisually();
// Returns true if the <video> is being cloned visually to another
// <video> element (see cloneElementVisually).
[Func="IsChromeOrXBLOrUAWidget"]
readonly attribute boolean isCloningElementVisually;
};
// https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#idl-def-HTMLVideoElement

View File

@ -106,10 +106,6 @@ class PictureInPictureChild extends ActorChild {
}, { once: true });
this.content.addEventListener("unload", () => {
let video = gWeakVideo && gWeakVideo.get();
if (video) {
video.stopCloningElementVisually();
}
gWeakVideo = null;
}, { once: true });
}

View File

@ -38,28 +38,19 @@ this.VideoControlsWidget = class {
/*
* Actually switch the implementation.
* - With "controls" set, the VideoControlsImplWidget controls should load.
* - Without it, on mobile, the NoControlsMobileImplWidget should load, so
* - Without it, on mobile, the NoControlsImplWidget should load, so
* the user could see the click-to-play button when the video/audio is blocked.
* - Without it, on desktop, the NoControlsPictureInPictureImpleWidget should load
* if the video is being viewed in Picture-in-Picture.
*/
switchImpl() {
let newImpl;
if (this.element.controls) {
newImpl = VideoControlsImplWidget;
} else if (this.isMobile) {
newImpl = NoControlsMobileImplWidget;
} else if (VideoControlsWidget.isPictureInPictureVideo(this.element)) {
newImpl = NoControlsPictureInPictureImplWidget;
newImpl = NoControlsImplWidget;
}
// Skip if we are asked to load the same implementation, and
// the underlying element state hasn't changed in ways that we
// care about. This can happen if the property is set again
// without a value change.
if (this.impl &&
this.impl.constructor == newImpl &&
this.impl.elementStateMatches(this.element)) {
// Skip if we are asked to load the same implementation.
// This can happen if the property is set again w/o value change.
if (this.impl && this.impl.constructor == newImpl) {
return;
}
if (this.impl) {
@ -82,10 +73,6 @@ this.VideoControlsWidget = class {
this.shadowRoot.firstChild.remove();
delete this.impl;
}
static isPictureInPictureVideo(someVideo) {
return someVideo.isCloningElementVisually;
}
};
this.VideoControlsImplWidget = class {
@ -118,7 +105,6 @@ this.VideoControlsImplWidget = class {
controlsOverlay: null,
fullscreenButton: null,
layoutControls: null,
isShowingPictureInPictureMessage: false,
textTracksCount: 0,
videoEvents: ["play", "pause", "ended", "volumechange", "loadeddata",
@ -261,8 +247,6 @@ this.VideoControlsImplWidget = class {
this.statusIcon.setAttribute("type", "error");
this.updateErrorText();
this.setupStatusFader(true);
} else if (VideoControlsWidget.isPictureInPictureVideo(this.video)) {
this.setShowPictureInPictureMessage(true);
}
let adjustableControls = [
@ -381,8 +365,7 @@ this.VideoControlsImplWidget = class {
!this.video.autoplay);
// Hide the overlay if the video time is non-zero or if an error occurred to workaround bug 718107.
let shouldClickToPlayShow = shouldShow && !this.isAudioOnly &&
this.video.currentTime == 0 && !this.hasError() &&
!this.isShowingPictureInPictureMessage;
this.video.currentTime == 0 && !this.hasError();
this.startFade(this.clickToPlay, shouldClickToPlayShow, true);
this.startFade(this.controlBar, shouldShow, true);
},
@ -534,7 +517,7 @@ this.VideoControlsImplWidget = class {
case "loadstart":
this.maxCurrentTimeSeen = 0;
this.controlsSpacer.removeAttribute("aria-label");
this.statusOverlay.removeAttribute("status");
this.statusOverlay.removeAttribute("error");
this.statusIcon.setAttribute("type", "throbber");
this.isAudioOnly = this.video.localName == "audio";
this.setPlayButtonState(true);
@ -767,16 +750,6 @@ this.VideoControlsImplWidget = class {
this.hasSources());
},
setShowPictureInPictureMessage(showMessage) {
if (showMessage) {
this.pictureInPictureOverlay.removeAttribute("hidden");
} else {
this.pictureInPictureOverlay.setAttribute("hidden", true);
}
this.isShowingPictureInPictureMessage = showMessage;
},
hasSources() {
if (this.video.hasAttribute("src") &&
this.video.getAttribute("src") !== "") {
@ -801,32 +774,32 @@ this.VideoControlsImplWidget = class {
if (v.error) {
switch (v.error.code) {
case v.error.MEDIA_ERR_ABORTED:
error = "statusErrorAborted";
error = "errorAborted";
break;
case v.error.MEDIA_ERR_NETWORK:
error = "statusErrorNetwork";
error = "errorNetwork";
break;
case v.error.MEDIA_ERR_DECODE:
error = "statusErrorDecode";
error = "errorDecode";
break;
case v.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
error = v.networkState == v.NETWORK_NO_SOURCE ?
"statusErrorNoSource" :
"statusErrorSrcNotSupported";
"errorNoSource" :
"errorSrcNotSupported";
break;
default:
error = "statusErrorGeneric";
error = "errorGeneric";
break;
}
} else if (v.networkState == v.NETWORK_NO_SOURCE) {
error = "statusErrorNoSource";
error = "errorNoSource";
} else {
return; // No error found.
}
let label = this.shadowRoot.getElementById(error);
this.controlsSpacer.setAttribute("aria-label", label.textContent);
this.statusOverlay.setAttribute("status", error);
this.statusOverlay.setAttribute("error", error);
},
formatTime(aTime, showHours = false) {
@ -1968,7 +1941,6 @@ this.VideoControlsImplWidget = class {
this.positionDurationBox = this.shadowRoot.getElementById("positionDurationBox");
this.statusOverlay = this.shadowRoot.getElementById("statusOverlay");
this.controlsOverlay = this.shadowRoot.getElementById("controlsOverlay");
this.pictureInPictureOverlay = this.shadowRoot.getElementById("pictureInPictureOverlay");
this.controlsSpacer = this.shadowRoot.getElementById("controlsSpacer");
this.clickToPlay = this.shadowRoot.getElementById("clickToPlay");
this.fullscreenButton = this.shadowRoot.getElementById("fullscreenButton");
@ -2234,17 +2206,12 @@ this.VideoControlsImplWidget = class {
<div id="controlsContainer" class="controlsContainer" role="none">
<div id="statusOverlay" class="statusOverlay stackItem" hidden="true">
<div id="statusIcon" class="statusIcon"></div>
<span class="statusLabel" id="statusErrorAborted">&error.aborted;</span>
<span class="statusLabel" id="statusErrorNetwork">&error.network;</span>
<span class="statusLabel" id="statusErrorDecode">&error.decode;</span>
<span class="statusLabel" id="statusErrorSrcNotSupported">&error.srcNotSupported;</span>
<span class="statusLabel" id="statusErrorNoSource">&error.noSource2;</span>
<span class="statusLabel" id="statusErrorGeneric">&error.generic;</span>
</div>
<div id="pictureInPictureOverlay" class="pictureInPictureOverlay stackItem" status="pictureInPicture" hidden="true">
<div class="statusIcon" type="pictureInPicture"></div>
<span class="statusLabel" id="statusPictureInPicture">&status.pictureInPicture;</span>
<span class="errorLabel" id="errorAborted">&error.aborted;</span>
<span class="errorLabel" id="errorNetwork">&error.network;</span>
<span class="errorLabel" id="errorDecode">&error.decode;</span>
<span class="errorLabel" id="errorSrcNotSupported">&error.srcNotSupported;</span>
<span class="errorLabel" id="errorNoSource">&error.noSource2;</span>
<span class="errorLabel" id="errorGeneric">&error.generic;</span>
</div>
<div id="controlsOverlay" class="controlsOverlay stackItem" role="none">
@ -2298,11 +2265,6 @@ this.VideoControlsImplWidget = class {
this.shadowRoot.importNodeAndAppendChildAt(this.shadowRoot, parserDoc.documentElement, true);
}
elementStateMatches(element) {
let elementInPiP = VideoControlsWidget.isPictureInPictureVideo(element);
return this.isShowingPictureInPictureMessage == elementInPiP;
}
destructor() {
this.Utils.terminate();
this.TouchUtils.terminate();
@ -2330,7 +2292,7 @@ this.VideoControlsImplWidget = class {
}
};
this.NoControlsMobileImplWidget = class {
this.NoControlsImplWidget = class {
constructor(shadowRoot) {
this.shadowRoot = shadowRoot;
this.element = shadowRoot.host;
@ -2435,10 +2397,6 @@ this.NoControlsMobileImplWidget = class {
this.Utils.video.dispatchEvent(new this.window.CustomEvent("MozNoControlsVideoBindingAttached"));
}
elementStateMatches(element) {
return true;
}
destructor() {
this.Utils.terminate();
}
@ -2466,46 +2424,3 @@ this.NoControlsMobileImplWidget = class {
this.shadowRoot.importNodeAndAppendChildAt(this.shadowRoot, parserDoc.documentElement, true);
}
};
this.NoControlsPictureInPictureImplWidget = class {
constructor(shadowRoot) {
this.shadowRoot = shadowRoot;
this.element = shadowRoot.host;
this.document = this.element.ownerDocument;
this.window = this.document.defaultView;
}
onsetup() {
this.generateContent();
}
elementStateMatches(element) {
return true;
}
destructor() {
}
generateContent() {
/*
* Pass the markup through XML parser purely for the reason of loading the localization DTD.
* Remove it when migrate to Fluent.
*/
const parser = new this.window.DOMParser();
let parserDoc = parser.parseFromString(`<!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" type="text/css" 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>
<span class="statusLabel" id="statusPictureInPicture">&status.pictureInPicture;</span>
</div>
<div class="controlsOverlay stackItem"></div>
</div>
</div>`, "application/xml");
this.shadowRoot.importNodeAndAppendChildAt(this.shadowRoot, parserDoc.documentElement, true);
}
};

View File

@ -34,8 +34,6 @@
<!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 (scrubberScale.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

View File

@ -107,6 +107,5 @@ toolkit.jar:
skin/classic/global/plugins/contentPluginStripe.png (../../shared/plugins/contentPluginStripe.png)
#ifdef NIGHTLY_BUILD
skin/classic/global/pictureinpicture/player.css (../../shared/pictureinpicture/player.css)
skin/classic/global/media/pictureinpicture.svg (../../shared/media/pictureinpicture.svg)
#endif

View File

@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<g fill="none" fill-rule="evenodd" stroke="none" stroke-width="1">
<path stroke="context-stroke" d="M0.5 0.5h13v13h-13z"/>
<path fill="context-fill" d="M8 10h8v6h-8z"/>
<path stroke="context-stroke" d="M0.5 5.5h7v-5h-5.5a1.5 1.5 0 0 0 -1.5 1.5v3.5z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 357 B

View File

@ -411,26 +411,11 @@
background: url(chrome://global/skin/media/stalled.png) no-repeat center;
}
.statusIcon[type="error"],
.statusIcon[type="pictureInPicture"] {
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
.statusIcon[type="error"] {
min-width: 70px;
min-height: 60px;
background-image: url(chrome://global/skin/media/error.png);
}
.statusIcon[type="pictureInPicture"] {
min-width: 84px;
min-height: 84px;
background-image: url(chrome://global/skin/media/pictureinpicture.svg);
-moz-context-properties: fill, stroke;
fill: #fff;
stroke: #fff;
background: url(chrome://global/skin/media/error.png) no-repeat center;
background-size: contain;
}
/* Overlay Play button */
@ -468,17 +453,8 @@
opacity: 0;
}
.pictureInPictureOverlay {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
opacity: 1;
background-color: rgb(12, 12, 13);
}
/* Status description formatting */
.statusLabel {
/* Error description formatting */
.errorLabel {
padding: 0 10px;
text-align: center;
font: message-box;
@ -486,17 +462,22 @@
color: #ffffff;
}
.statusLabel {
.errorLabel {
display: none;
}
[status="errorAborted"] > [id="statusErrorAborted"],
[status="errorNetwork"] > [id="statusErrorNetwork"],
[status="errorDecode"] > [id="statusErrorDecode"],
[status="errorSrcNotSupported"] > [id="statusErrorSrcNotSupported"],
[status="errorNoSource"] > [id="statusErrorNoSource"],
[status="errorGeneric"] > [id="statusErrorGeneric"],
[status="pictureInPicture"] > [id="statusPictureInPicture"] {
[error="errorAborted"] > [anonid="errorAborted"],
[error="errorNetwork"] > [anonid="errorNetwork"],
[error="errorDecode"] > [anonid="errorDecode"],
[error="errorSrcNotSupported"] > [anonid="errorSrcNotSupported"],
[error="errorNoSource"] > [anonid="errorNoSource"],
[error="errorGeneric"] > [anonid="errorGeneric"],
[error="errorAborted"] > [id="errorAborted"],
[error="errorNetwork"] > [id="errorNetwork"],
[error="errorDecode"] > [id="errorDecode"],
[error="errorSrcNotSupported"] > [id="errorSrcNotSupported"],
[error="errorNoSource"] > [id="errorNoSource"],
[error="errorGeneric"] > [id="errorGeneric"] {
display: inline;
}