Backed out 6 changesets (bug 1531101) for Mochitest failure in toolkit/content/tests/widgets/test_videocontrols_error.html. CLOSED TREE
authorDorel Luca <dluca@mozilla.com>
Tue, 12 Mar 2019 02:04:54 +0200
changeset 524454 b9b0378c5e0bd749b7904c2a5ccca74c9683bf42
parent 524453 02b387ef172ee8e00ba33eb630def6cb0784b05b
child 524455 e5e2e0d4eb054eb3b88748e5ef9dfadc7d2f2697
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1531101
milestone67.0a1
backs out10e9bbf2d1df3b261a86356d3e9e15da962a9568
44d96bcc51f75d7a1a8c44d60dd7dc2131348c56
4a4b44c3481a20676eaf16deabb8e32f18bc8bcf
12bcda2d76db12ba1a1f05b48d6f71484561c600
5887b55233c2695f8ee05826303abae9e34d7652
13a0c61ed4fcc2383ad2ca20f352ce6b43f85904
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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)
dom/html/HTMLVideoElement.cpp
dom/html/HTMLVideoElement.h
dom/webidl/HTMLVideoElement.webidl
toolkit/actors/PictureInPictureChild.jsm
toolkit/content/widgets/videocontrols.js
toolkit/locales/en-US/chrome/global/videocontrols.dtd
toolkit/themes/shared/jar.inc.mn
toolkit/themes/shared/media/pictureinpicture.svg
toolkit/themes/shared/media/videocontrols.css
--- a/dom/html/HTMLVideoElement.cpp
+++ b/dom/html/HTMLVideoElement.cpp
@@ -476,29 +476,19 @@ void HTMLVideoElement::CloneElementVisua
   if (!aTargetVideo.SetVisualCloneSource(this)) {
     mVisualCloneTarget = nullptr;
     rv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   aTargetVideo.SetMediaInfo(mMediaInfo);
 
-  if (IsInComposedDoc()) {
-    NotifyUAWidgetSetupOrChange();
-  }
-
   MaybeBeginCloningVisually();
 }
 
-void HTMLVideoElement::StopCloningElementVisually() {
-  if (mVisualCloneTarget) {
-    EndCloningVisually();
-  }
-}
-
 void HTMLVideoElement::MaybeBeginCloningVisually() {
   if (!mVisualCloneTarget) {
     return;
   }
 
   if (mDecoder) {
     MediaDecoderStateMachine* mdsm = mDecoder->GetStateMachine();
     VideoFrameContainer* container =
@@ -531,16 +521,12 @@ void HTMLVideoElement::EndCloningVisuall
     if (container && mVisualCloneTarget->mSelectedVideoStreamTrack) {
       mVisualCloneTarget->mSelectedVideoStreamTrack->RemoveVideoOutput(
           container);
     }
   }
 
   Unused << mVisualCloneTarget->SetVisualCloneSource(nullptr);
   Unused << SetVisualCloneTarget(nullptr);
-
-  if (IsInComposedDoc()) {
-    NotifyUAWidgetSetupOrChange();
-  }
 }
 
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/html/HTMLVideoElement.h
+++ b/dom/html/HTMLVideoElement.h
@@ -134,20 +134,16 @@ class HTMLVideoElement final : public HT
   }
 
   bool MozIsOrientationLocked() const { return mIsOrientationLocked; }
 
   void SetMozIsOrientationLocked(bool aLock) { mIsOrientationLocked = aLock; }
 
   void CloneElementVisually(HTMLVideoElement& aTarget, ErrorResult& rv);
 
-  void StopCloningElementVisually();
-
-  bool IsCloningElementVisually() const { return !!mVisualCloneTarget; }
-
  protected:
   virtual ~HTMLVideoElement();
 
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aGivenProto) override;
 
   /**
    * We create video wakelock when the video is playing and release it when
--- a/dom/webidl/HTMLVideoElement.webidl
+++ b/dom/webidl/HTMLVideoElement.webidl
@@ -54,25 +54,15 @@ partial interface HTMLVideoElement {
   [Pref="media.videocontrols.lock-video-orientation", Func="IsChromeOrXBLOrUAWidget"]
     attribute boolean mozIsOrientationLocked;
 
   // Clones the frames playing in this <video> to the target. Cloning
   // when either node is removed from their DOM trees. Throws if one or
   // 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
 partial interface HTMLVideoElement {
   [Func="mozilla::dom::MediaSource::Enabled", NewObject]
   VideoPlaybackQuality getVideoPlaybackQuality();
 };
--- a/toolkit/actors/PictureInPictureChild.jsm
+++ b/toolkit/actors/PictureInPictureChild.jsm
@@ -101,16 +101,12 @@ class PictureInPictureChild extends Acto
     originatingVideo.cloneElementVisually(playerVideo);
 
     let originatingWindow = originatingVideo.ownerGlobal;
     originatingWindow.addEventListener("unload", (e) => {
       this.closePictureInPicture(originatingVideo);
     }, { once: true });
 
     this.content.addEventListener("unload", () => {
-      let video = gWeakVideo && gWeakVideo.get();
-      if (video) {
-        video.stopCloningElementVisually();
-      }
       gWeakVideo = null;
     }, { once: true });
   }
 }
--- a/toolkit/content/widgets/videocontrols.js
+++ b/toolkit/content/widgets/videocontrols.js
@@ -33,38 +33,29 @@ this.VideoControlsWidget = class {
    */
   onchange() {
     this.switchImpl();
   }
 
   /*
    * 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) {
       this.impl.destructor();
       this.shadowRoot.firstChild.remove();
     }
     if (newImpl) {
       this.impl = new newImpl(this.shadowRoot);
@@ -77,20 +68,16 @@ this.VideoControlsWidget = class {
   destructor() {
     if (!this.impl) {
       return;
     }
     this.impl.destructor();
     this.shadowRoot.firstChild.remove();
     delete this.impl;
   }
-
-  static isPictureInPictureVideo(someVideo) {
-    return someVideo.isCloningElementVisually;
-  }
 };
 
 this.VideoControlsImplWidget = class {
   constructor(shadowRoot) {
     this.shadowRoot = shadowRoot;
     this.element = shadowRoot.host;
     this.document = this.element.ownerDocument;
     this.window = this.document.defaultView;
@@ -113,17 +100,16 @@ this.VideoControlsImplWidget = class {
       progressBar: null,
       bufferBar: null,
       statusOverlay: null,
       controlsSpacer: null,
       clickToPlay: null,
       controlsOverlay: null,
       fullscreenButton: null,
       layoutControls: null,
-      isShowingPictureInPictureMessage: false,
 
       textTracksCount: 0,
       videoEvents: ["play", "pause", "ended", "volumechange", "loadeddata",
                     "loadstart", "timeupdate", "progress",
                     "playing", "waiting", "canplay", "canplaythrough",
                     "seeking", "seeked", "emptied", "loadedmetadata",
                     "error", "suspend", "stalled",
                     "mozvideoonlyseekbegin", "mozvideoonlyseekcompleted"],
@@ -256,18 +242,16 @@ this.VideoControlsImplWidget = class {
         }
 
         // Set the current status icon.
         if (this.hasError()) {
           this.startFadeOut(this.clickToPlay, true);
           this.statusIcon.setAttribute("type", "error");
           this.updateErrorText();
           this.setupStatusFader(true);
-        } else if (VideoControlsWidget.isPictureInPictureVideo(this.video)) {
-          this.setShowPictureInPictureMessage(true);
         }
 
         let adjustableControls = [
           ...this.prioritizedControls,
           this.controlBar,
           this.clickToPlay,
         ];
 
@@ -376,18 +360,17 @@ this.VideoControlsImplWidget = class {
         // For videos with |autoplay| set, we'll leave the controls initially hidden,
         // so that they don't get in the way of the playing video. Otherwise we'll
         // go ahead and reveal the controls now, so they're an obvious user cue.
         var shouldShow = !this.dynamicControls ||
                          (this.video.paused &&
                          !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);
       },
 
       get dynamicControls() {
         // Don't fade controls for <audio> elements.
         var enabled = !this.isAudioOnly;
 
@@ -529,17 +512,17 @@ this.VideoControlsImplWidget = class {
             break;
           case "loadeddata":
             this.firstFrameShown = true;
             this.setupStatusFader();
             break;
           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);
             this.setupNewLoadState();
             this.setupStatusFader();
             break;
           case "progress":
             this.statusIcon.removeAttribute("stalled");
@@ -762,26 +745,16 @@ this.VideoControlsImplWidget = class {
         // do this intentionally to work around requires-user-interaction to
         // play restrictions, and we don't want to display a debug message
         // if that's the case.
         return this.video.error != null ||
                (this.video.networkState == this.video.NETWORK_NO_SOURCE &&
                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") !== "") {
           return true;
         }
         for (var child = this.video.firstChild;
              child !== null;
              child = child.nextElementSibling) {
@@ -796,42 +769,42 @@ this.VideoControlsImplWidget = class {
         let error;
         let v = this.video;
         // It is possible to have both v.networkState == NETWORK_NO_SOURCE
         // as well as v.error being non-null. In this case, we will show
         // the v.error.code instead of the v.networkState error.
         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) {
         // Format the duration as "h:mm:ss" or "m:ss"
         aTime = Math.round(aTime / 1000);
         let hours = Math.floor(aTime / 3600);
         let mins  = Math.floor((aTime % 3600) / 60);
         let secs  = Math.floor(aTime % 60);
@@ -1963,17 +1936,16 @@ this.VideoControlsImplWidget = class {
         this.bufferBar = this.shadowRoot.getElementById("bufferBar");
         this.scrubberStack = this.shadowRoot.getElementById("scrubberStack");
         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");
-        this.pictureInPictureOverlay = this.shadowRoot.getElementById("pictureInPictureOverlay");
         this.controlsSpacer = this.shadowRoot.getElementById("controlsSpacer");
         this.clickToPlay = this.shadowRoot.getElementById("clickToPlay");
         this.fullscreenButton = this.shadowRoot.getElementById("fullscreenButton");
         this.castingButton = this.shadowRoot.getElementById("castingButton");
         this.closedCaptionButton = this.shadowRoot.getElementById("closedCaptionButton");
         this.textTrackList = this.shadowRoot.getElementById("textTrackList");
 
         if (this.positionDurationBox) {
@@ -2229,27 +2201,22 @@ this.VideoControlsImplWidget = class {
       <!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 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">
             <div class="controlsSpacerStack">
               <div id="controlsSpacer" class="controlsSpacer stackItem" role="none"></div>
               <div id="clickToPlay" class="clickToPlay" hidden="true"></div>
             </div>
 
@@ -2293,21 +2260,16 @@ this.VideoControlsImplWidget = class {
             </div>
             <div id="textTrackList" class="textTrackList" hidden="true" offlabel="&closedCaption.off;"></div>
           </div>
         </div>
       </div>`, "application/xml");
     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();
     this.Utils.updateOrientationState(false);
   }
 
   _setupEventListeners() {
     this.shadowRoot.firstChild.addEventListener("mouseover", event => {
@@ -2325,17 +2287,17 @@ this.VideoControlsImplWidget = class {
     this.shadowRoot.firstChild.addEventListener("mousemove", event => {
       if (!this.Utils.isTouchControls) {
         this.Utils.onMouseMove(event);
       }
     });
   }
 };
 
-this.NoControlsMobileImplWidget = class {
+this.NoControlsImplWidget = class {
   constructor(shadowRoot) {
     this.shadowRoot = shadowRoot;
     this.element = shadowRoot.host;
     this.document = this.element.ownerDocument;
     this.window = this.document.defaultView;
   }
 
   onsetup() {
@@ -2430,20 +2392,16 @@ this.NoControlsMobileImplWidget = class 
           });
         }
       },
     };
     this.Utils.init(this.shadowRoot);
     this.Utils.video.dispatchEvent(new this.window.CustomEvent("MozNoControlsVideoBindingAttached"));
   }
 
-  elementStateMatches(element) {
-    return true;
-  }
-
   destructor() {
     this.Utils.terminate();
   }
 
   generateContent() {
     /*
      * Pass the markup through XML parser purely for the reason of loading the localization DTD.
      * Remove it when migrate to Fluent.
@@ -2461,51 +2419,8 @@ this.NoControlsMobileImplWidget = class 
               <div id="clickToPlay" class="clickToPlay"></div>
             </div>
           </div>
         </div>
       </div>`, "application/xml");
     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);
-  }
-};
--- a/toolkit/locales/en-US/chrome/global/videocontrols.dtd
+++ b/toolkit/locales/en-US/chrome/global/videocontrols.dtd
@@ -29,18 +29,16 @@
 
 <!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 (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
 "6:00:00", result string would be "5:00 of 6:00:00 elapsed".
 -->
 <!ENTITY scrubberScale.nameFormat "#1 of #2 elapsed">
 
 <!-- LOCALIZATION NOTE (positionAndDuration.nameFormat): the #1 string is the current
--- a/toolkit/themes/shared/jar.inc.mn
+++ b/toolkit/themes/shared/jar.inc.mn
@@ -102,11 +102,10 @@ toolkit.jar:
   skin/classic/global/plugins/plugin-blocked.svg            (../../shared/plugins/plugin-blocked.svg)
   skin/classic/global/plugins/pluginGeneric.svg             (../../shared/extensions/category-plugins.svg)
   skin/classic/global/plugins/pluginProblem.css             (../../shared/plugins/pluginProblem.css)
   skin/classic/global/plugins/contentPluginBlocked.png      (../../shared/plugins/contentPluginBlocked.png)
   skin/classic/global/plugins/contentPluginCrashed.png      (../../shared/plugins/contentPluginCrashed.png)
   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
 
deleted file mode 100644
--- a/toolkit/themes/shared/media/pictureinpicture.svg
+++ /dev/null
@@ -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>
\ No newline at end of file
--- a/toolkit/themes/shared/media/videocontrols.css
+++ b/toolkit/themes/shared/media/videocontrols.css
@@ -406,36 +406,21 @@
 .controlsContainer:not(.mobile) .statusIcon[type="throbber"] {
   background: url(chrome://global/skin/media/throbber.png) no-repeat center;
 }
 
 .controlsContainer:not(.mobile) .statusIcon[type="throbber"][stalled] {
   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 */
 .clickToPlay {
   min-width: var(--clickToPlay-size);
   min-height: var(--clickToPlay-size);
   border-radius: 50%;
   background-image: url(chrome://global/skin/media/playButton.svg);
@@ -463,45 +448,41 @@
   display: none;
 }
 
 .statusOverlay[fadeout],
 .statusOverlay[error] + .controlsOverlay > .controlsSpacerStack {
   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;
   font-size: 14px;
   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;
 }
 
 %ifdef XP_WIN
 @media (-moz-windows-default-theme: 0) {
   .controlsSpacer,
   .clickToPlay {
     background-color: transparent;