Backed out 9 changesets (bug 1126230) for Mulet Gij(25) and M(5) failures
authorNigel Babu <nigelbabu@gmail.com>
Fri, 02 Oct 2015 13:39:20 +0530
changeset 286419 c3ac8787049490102c9df6dc32245a8c5add8c0a
parent 286418 35958f485b2987e8b54fa3e66500174ba5cda867
child 286420 c7933be0b031390aaa4e70676124ba28f9cb6278
push idunknown
push userunknown
push dateunknown
bugs1126230
milestone44.0a1
backs out8a9d8a55618352a0c4327bf32b72eca24f0cafe7
441b55f015c2b6bdd90736a1a4c92d623502a594
7bfa2a2d4e29989b9057afbc01b79979662a1fa1
b55511536c65e45bea5d3769c9abf8f8fda1b06c
ada76e419aac5fc15f3ba022a729e30c26d6d98c
745d659bef49d125d32ef0c340e979bd17162490
7c303cc4c30baa310569bf266b4c9e40eab4b7fd
8bf708acbad4bebe9fab68958da532296eb7b07d
590404aac3573ac8def5d8caf2af61f013b79338
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 9 changesets (bug 1126230) for Mulet Gij(25) and M(5) failures Backed out changeset 8a9d8a556183 (bug 1126230) Backed out changeset 441b55f015c2 (bug 1126230) Backed out changeset 7bfa2a2d4e29 (bug 1126230) Backed out changeset b55511536c65 (bug 1126230) Backed out changeset ada76e419aac (bug 1126230) Backed out changeset 745d659bef49 (bug 1126230) Backed out changeset 7c303cc4c30b (bug 1126230) Backed out changeset 8bf708acbad4 (bug 1126230) Backed out changeset 590404aac357 (bug 1126230)
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsIDocument.h
dom/html/test/file_fullscreen-ancestor-stacking-context.html
dom/html/test/file_fullscreen-top-layer.html
dom/html/test/mochitest.ini
dom/html/test/test_fullscreen-api.html
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsDisplayList.h
layout/base/nsDocumentViewer.cpp
layout/generic/nsFrame.cpp
layout/generic/nsViewportFrame.cpp
layout/generic/nsViewportFrame.h
layout/style/full-screen-override.css
layout/style/jar.mn
layout/style/nsCSSPropList.h
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
layout/style/nsLayoutStylesheetCache.cpp
layout/style/nsLayoutStylesheetCache.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleConsts.h
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/ua.css
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -11435,29 +11435,16 @@ nsDocument::FullScreenStackTop()
   uint32_t last = mFullScreenStack.Length() - 1;
   nsCOMPtr<Element> element(do_QueryReferent(mFullScreenStack[last]));
   NS_ASSERTION(element, "Should have full-screen element!");
   NS_ASSERTION(element->IsInDoc(), "Full-screen element should be in doc");
   NS_ASSERTION(element->OwnerDoc() == this, "Full-screen element should be in this doc");
   return element;
 }
 
-/* virtual */ nsTArray<Element*>
-nsDocument::GetFullscreenStack() const
-{
-  nsTArray<Element*> elements;
-  for (const nsWeakPtr& ptr : mFullScreenStack) {
-    if (nsCOMPtr<Element> elem = do_QueryReferent(ptr)) {
-      MOZ_ASSERT(elem->State().HasState(NS_EVENT_STATE_FULL_SCREEN));
-      elements.AppendElement(elem);
-    }
-  }
-  return elements;
-}
-
 // Returns true if aDoc is in the focused tab in the active window.
 static bool
 IsInActiveTab(nsIDocument* aDoc)
 {
   nsCOMPtr<nsIDocShell> docshell = aDoc->GetDocShell();
   if (!docshell) {
     return false;
   }
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -1202,17 +1202,16 @@ public:
   virtual nsresult GetStateObject(nsIVariant** aResult) override;
 
   virtual nsDOMNavigationTiming* GetNavigationTiming() const override;
   virtual nsresult SetNavigationTiming(nsDOMNavigationTiming* aTiming) override;
 
   virtual Element* FindImageMap(const nsAString& aNormalizedMapName) override;
 
   virtual Element* GetFullScreenElement() override;
-  virtual nsTArray<Element*> GetFullscreenStack() const override;
   virtual void AsyncRequestFullScreen(
     mozilla::UniquePtr<FullscreenRequest>&& aRequest) override;
   virtual void RestorePreviousFullScreenState() override;
   virtual bool IsFullscreenLeaf() override;
   virtual bool IsFullScreenDoc() override;
   virtual nsresult
     RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement) override;
 
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -150,18 +150,18 @@ template<typename> class Sequence;
 
 template<typename, typename> class CallbackObjectHolder;
 typedef CallbackObjectHolder<NodeFilter, nsIDOMNodeFilter> NodeFilterHolder;
 
 } // namespace dom
 } // namespace mozilla
 
 #define NS_IDOCUMENT_IID \
-{ 0x5f51e18c, 0x9e0e, 0x4dc0, \
-  { 0x9f, 0x08, 0x7a, 0x32, 0x65, 0x52, 0xea, 0x11 } }
+{ 0x72391609, 0x673d, 0x4bec, \
+  { 0xbd, 0x75, 0x64, 0xbf, 0x1f, 0x6a, 0x6b, 0x5e } }
 
 // Enum for requesting a particular type of document when creating a doc
 enum DocumentFlavor {
   DocumentFlavorLegacyGuess, // compat with old code until made HTML5-compliant
   DocumentFlavorHTML, // HTMLDocument with HTMLness bit set to true
   DocumentFlavorSVG, // SVGDocument
   DocumentFlavorPlain, // Just a Document
 };
@@ -1090,21 +1090,16 @@ public:
    * Returns the element which either requested DOM full-screen mode, or
    * contains the element which requested DOM full-screen mode if the
    * requestee is in a subdocument. Note this element must be *in*
    * this document.
    */
   virtual Element* GetFullScreenElement() = 0;
 
   /**
-   * Returns all elements in the fullscreen stack in the insertion order.
-   */
-  virtual nsTArray<Element*> GetFullscreenStack() const = 0;
-
-  /**
    * Asynchronously requests that the document make aElement the fullscreen
    * element, and move into fullscreen mode. The current fullscreen element
    * (if any) is pushed onto the fullscreen element stack, and it can be
    * returned to fullscreen status by calling RestorePreviousFullScreenState().
    *
    * Note that requesting fullscreen in a document also makes the element which
    * contains this document in this document's parent document fullscreen. i.e.
    * the <iframe> or <browser> that contains this document is also mode
new file mode 100644
--- /dev/null
+++ b/dom/html/test/file_fullscreen-ancestor-stacking-context.html
@@ -0,0 +1,134 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1056203
+-->
+<head>
+  <title>Test for Bug 1056203</title>
+</head>
+<body>
+
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1056203">Mozilla Bug 1056203</a>
+<p id="display">
+  <div id="grandparent">
+    <div id="parent">
+      <div id="fullscreenElem">
+        <div id="child"></div>
+      </div>
+    </div>
+  </div>
+</p>
+<pre id="test">
+<script type="application/javascript;version=1.7">
+
+/** Test for Bug 1056203 **/
+/* This test ensures that the ancestors of a full-screened element cannot be
+   restyled to create a stacking context, even with !important. */
+
+/* NOTE: The following hash should include each of the properties from
+   layout/style/full-screen-override.css (except that this list uses the DOM
+   versions of the property names -- e.g. "zIndex" instead of "z-index").
+   Both lists should include every property that is able to induce an element
+   to form a stacking context. */
+const gPropertyTestDecls = {
+//"domPropName": "prop-name: some-non-initial-value",
+  "zIndex":      "z-index: 5",
+  "opacity":     "opacity: 0.8",
+  "mask":        "mask: url(#mymask)",
+  "clip":        "clip: rect(0 0 0 0)",
+  "clipPath":    "clip-path: url(#mypath)",
+  "filter":      "filter: url(#myfilter)",
+  "transform":   "transform: translate(0)",
+  "willChange":  "will-change: transform"
+};
+
+// populated in populateInitialVals
+let gPropertyInitialVals = {};
+
+function begin() {
+  populateInitialVals();
+
+  // FIRST: Assert that the properties in gPropertyTestDecls can be set
+  // on each of our tested elements, before we enter full-screen mode.
+  var timeDescrip = "not yet fullscreen";
+  testPropertiesOnElem("grandparent", true);
+  testPropertiesOnElem("parent", true);
+  testPropertiesOnElem("fullscreenElem", true);
+  testPropertiesOnElem("child", true);
+
+  document.addEventListener("mozfullscreenchange", handleFullscreen, false);
+  fullscreenElem.mozRequestFullScreen();
+}
+
+function handleFullscreen(e) {
+  opener.ok(document.mozFullScreen, "should've entered full-screen mode");
+
+  // SECOND: Assert that the properties in gPropertyTestDecls can *NOT* be
+  // set (their decls have no effect) on ancestors of the full-screen elem.
+  testPropertiesOnElem("parent", false);
+  testPropertiesOnElem("grandparent", false);
+  testPropertiesOnElem("fullscreenElem", true);
+  testPropertiesOnElem("child", true);
+
+  // Un-register listener, so we aren't re-triggered when document is torn
+  // down & taken out of full-screen mode:
+  document.removeEventListener("mozfullscreenchange", handleFullscreen);
+
+  // We're done! On to the next test:
+  opener.nextTest();
+};
+
+// Populates gPropertyTestDecls with the initial values of each property
+// in gPropertyTestDecls (based on document.documentElement's computed style)
+function populateInitialVals() {
+  // We'll read the initial values off of document.documentElement.
+  let cs = window.getComputedStyle(document.documentElement, "");
+  for (propName in gPropertyTestDecls) {
+    opener.ok(propName in cs,
+              "property '" + propName + "' used in this test should " +
+              "exist in computed style");
+    gPropertyInitialVals[propName] = cs[propName];
+  }
+}
+
+// For the element with id |elemId|, this method asserts that the property
+// decls in gPropertyTestDecls either *do* or *do not* have an effect on the
+// element's computed style, depending on the argument |isPropertyModifyable|.
+// The decls are tested both with & without "!important".
+function testPropertiesOnElem(elemId, isPropertyModifyable) {
+  const elem = document.getElementById(elemId);
+  opener.ok(elem, "expecting to find element with ID '" + elemId + "'");
+  const testFunc = isPropertyModifyable ? opener.isnot : opener.is;
+
+  for (propName in gPropertyTestDecls) {
+    let msg = elemId + ".style." + propName +" should ";
+    if (!isPropertyModifyable) {
+      msg += "NOT ";
+    }
+    msg += "be allowed to change away from initial value, ";
+    msg += document.mozFullScreen ? "after" : "before";
+    msg += " entering full-screen mode";
+
+    let decl = gPropertyTestDecls[propName];
+
+    // See if the test decl has any effect on computed style:
+    elem.setAttribute("style", decl);
+    testFunc(window.getComputedStyle(elem, "")[propName],
+             gPropertyInitialVals[propName],
+             msg);
+
+    // See if the test decl has any effect on computed style, w/ "!important":
+    elem.setAttribute("style", decl + " !important");
+    testFunc(window.getComputedStyle(elem, "")[propName],
+             gPropertyInitialVals[propName],
+             msg + " (with !important)");
+
+    elem.removeAttribute("style"); // clean up
+  }
+}
+
+</script>
+</pre>
+</body>
+
+</html>
deleted file mode 100644
--- a/dom/html/test/file_fullscreen-top-layer.html
+++ /dev/null
@@ -1,176 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <title>Test for Bug 1126230</title>
-  <style>
-    #back {
-      position: fixed !important;
-      z-index: 2147483647 !important;
-      top: 0 !important; left: 0 !important;
-      right: 0 !important; bottom: 0 !important;
-      width: 100% !important; height: 100% !important;
-    }
-    #parent {
-      position: fixed;
-      z-index: -2147483748;
-      width: 0; height: 0;
-      overflow: hidden;
-      opacity: 0;
-      mask: url(#mask);
-      clip: rect(0, 0, 0, 0);
-      clip-path: url(#clipPath);
-      filter: opacity(0%);
-      will-change: transform;
-      transform: scale(0);
-    }
-    /* The following styles are copied from ua.css to ensure that
-     * no other style change may trigger frame reconstruction */
-    :root {
-      overflow: hidden !important;
-    }
-    .two #fullscreen {
-      position: fixed !important;
-      top: 0 !important;
-      left: 0 !important;
-      right: 0 !important;
-      bottom: 0 !important;
-      z-index: 2147483647 !important;
-      width: 100% !important;
-      height: 100% !important;
-      margin: 0 !important;
-      min-width: 0 !important;
-      max-width: none !important;
-      min-height: 0 !important;
-      max-height: none !important;
-      box-sizing: border-box !important;
-    }
-  </style>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
-  <script type="text/javascript" src="file_fullscreen-utils.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1126230">Mozilla Bug 1126230</a>
-<div id="parent">
-  <div id="fullscreen" style="background-color: green"></div>
-</div>
-<div id="back" style="background-color: red"></div>
-<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
-  <defs>
-    <clipPath id="clipPath"></clipPath>
-    <mask id="mask"></mask>
-  </defs>
-</svg>
-<script>
-const gParentProperties = [
-  "position", "zIndex", "overflow",
-  "opacity", "mask", "clip", "clipPath",
-  "filter", "willChange", "transform"
-];
-
-var gInitialVals = {};
-
-const gParent = document.getElementById("parent");
-const gFullscreen = document.getElementById("fullscreen");
-const gBack = document.getElementById("back");
-
-function is(a, b, msg) {
-  opener.is(a, b, "[top-layer] " + msg);
-}
-
-function isnot(a, b, msg) {
-  opener.isnot(a, b, "[top-layer] " + msg);
-}
-
-function ok(cond, msg) {
-  opener.ok(cond, "[top-layer] " + msg);
-}
-
-function generatePureColorCanvas(width, height, color) {
-  const canvas = document.createElement("canvas");
-  canvas.width = width;
-  canvas.height = height;
-  const context = canvas.getContext("2d");
-  context.fillStyle = color;
-  context.fillRect(0, 0, width, height);
-  return canvas;
-}
-
-function checkWindowPureColor(color) {
-  const snapshot = SpecialPowers.snapshotRect(window);
-  const pureColor =
-    generatePureColorCanvas(snapshot.width, snapshot.height, color);
-  assertSnapshots(snapshot, pureColor, true, null, "snapshot", color);
-}
-
-function synthesizeMouseAtWindowCenter() {
-  synthesizeMouseAtPoint(innerWidth / 2, innerHeight / 2, {});
-}
-
-
-var tests = ["one", "two"];
-
-function begin() {
-  // record initial computed style of #parent
-  const style = getComputedStyle(gParent);
-  for (var prop of gParentProperties) {
-    gInitialVals[prop] = style[prop];
-  }
-
-  nextTest();
-}
-
-function nextTest() {
-  document.body.className = tests.shift();
-  // trigger a reflow to ensure the state of frames before fullscreen
-  gFullscreen.getBoundingClientRect();
-
-  ok(!document.mozFullScreen, "Shouldn't be in fullscreen");
-  // check window snapshot
-  checkWindowPureColor("red");
-  // simulate click
-  window.addEventListener("click", firstClick);
-  synthesizeMouseAtWindowCenter();
-}
-
-function firstClick(evt) {
-  window.removeEventListener("click", firstClick);
-  is(evt.target, gBack, "Click target should be #back before fullscreen");
-  addFullscreenChangeContinuation("enter", enterFullscreen);
-  gFullscreen.mozRequestFullScreen();
-}
-
-function enterFullscreen() {
-  ok(document.mozFullScreen, "Should now be in fullscreen");
-  // check window snapshot
-  checkWindowPureColor("green");
-  // check computed style of #parent
-  const style = getComputedStyle(gParent);
-  for (var prop of gParentProperties) {
-    is(style[prop], gInitialVals[prop],
-       `Computed style ${prop} of #parent should not be changed`);
-  }
-  // simulate click
-  window.addEventListener("click", secondClick);
-  synthesizeMouseAtWindowCenter();
-}
-
-function secondClick(evt) {
-  window.removeEventListener("click", secondClick);
-  is(evt.target, gFullscreen, "Click target should be #fullscreen now");
-  addFullscreenChangeContinuation("exit", exitFullscreen);
-  document.mozCancelFullScreen();
-}
-
-function exitFullscreen() {
-  if (tests.length > 0) {
-    nextTest();
-  } else {
-    opener.nextTest();
-  }
-}
-</script>
-</body>
-</html>
--- a/dom/html/test/mochitest.ini
+++ b/dom/html/test/mochitest.ini
@@ -41,33 +41,33 @@ support-files =
   file_bug209275_1.html
   file_bug209275_2.html
   file_bug209275_3.html
   file_bug297761.html
   file_bug417760.png
   file_bug893537.html
   file_formSubmission_img.jpg
   file_formSubmission_text.txt
+  file_fullscreen-ancestor-stacking-context.html
   file_fullscreen-api-keys.html
   file_fullscreen-api.html
   file_fullscreen-denied-inner.html
   file_fullscreen-denied.html
   file_fullscreen-esc-context-menu.html
   file_fullscreen-esc-exit-inner.html
   file_fullscreen-esc-exit.html
   file_fullscreen-hidden.html
   file_fullscreen-multiple-inner.html
   file_fullscreen-multiple.html
   file_fullscreen-navigation.html
   file_fullscreen-plugins.html
   file_fullscreen-rollback.html
   file_fullscreen-scrollbar.html
   file_fullscreen-selector.html
   file_fullscreen-svg-element.html
-  file_fullscreen-top-layer.html
   file_fullscreen-utils.js
   file_iframe_sandbox_a_if1.html
   file_iframe_sandbox_a_if10.html
   file_iframe_sandbox_a_if11.html
   file_iframe_sandbox_a_if12.html
   file_iframe_sandbox_a_if13.html
   file_iframe_sandbox_a_if14.html
   file_iframe_sandbox_a_if15.html
--- a/dom/html/test/test_fullscreen-api.html
+++ b/dom/html/test/test_fullscreen-api.html
@@ -23,30 +23,30 @@
 
 /** Tests for Bug 545812 **/
 SimpleTest.requestFlakyTimeout("untriaged");
 
 // Run the tests which go full-screen in new windows, as mochitests normally
 // run in an iframe, which by default will not have the allowfullscreen
 // attribute set, so full-screen won't work.
 var gTestWindows = [
+  "file_fullscreen-ancestor-stacking-context.html",
   "file_fullscreen-multiple.html",
   "file_fullscreen-rollback.html",
   "file_fullscreen-esc-context-menu.html",
   "file_fullscreen-esc-exit.html",
   "file_fullscreen-denied.html",
   "file_fullscreen-api.html",
   "file_fullscreen-api-keys.html",
   "file_fullscreen-plugins.html",
   "file_fullscreen-hidden.html",
   "file_fullscreen-svg-element.html",
   "file_fullscreen-navigation.html",
   "file_fullscreen-scrollbar.html",
-  "file_fullscreen-selector.html",
-  "file_fullscreen-top-layer.html"
+  "file_fullscreen-selector.html"
 ];
 
 var testWindow = null;
 var gTestIndex = 0;
 
 function finish() {
   SimpleTest.finish();
 }
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -739,21 +739,16 @@ public:
   // Frames destined for the kPopupList.
   nsAbsoluteItems           mPopupItems;
 #endif
 
   // Containing block information for out-of-flow frames.
   nsAbsoluteItems           mFixedItems;
   nsAbsoluteItems           mAbsoluteItems;
   nsAbsoluteItems           mFloatedItems;
-  // Items in the top layer are always fixed positioned children of the
-  // viewport frame. It differs from mFixedItems that the items here
-  // should not be caught by any other fixed-pos containing block like
-  // frames with transform or filter.
-  nsAbsoluteItems           mTopLayerItems;
 
   nsCOMPtr<nsILayoutHistoryState> mFrameState;
   // These bits will be added to the state bits of any frame we construct
   // using this state.
   nsFrameState              mAdditionalStateBits;
 
   // When working with the transform and filter properties, we want to hook
   // the abs-pos and fixed-pos lists together, since such
@@ -777,22 +772,21 @@ public:
   bool                      mCreatingExtraFrames;
 
   nsCOMArray<nsIContent>    mGeneratedTextNodesWithInitializer;
 
   TreeMatchContext          mTreeMatchContext;
 
   // Constructor
   // Use the passed-in history state.
-  nsFrameConstructorState(
-    nsIPresShell* aPresShell,
-    nsContainerFrame* aFixedContainingBlock,
-    nsContainerFrame* aAbsoluteContainingBlock,
-    nsContainerFrame* aFloatContainingBlock,
-    already_AddRefed<nsILayoutHistoryState> aHistoryState);
+  nsFrameConstructorState(nsIPresShell*          aPresShell,
+                          nsContainerFrame*      aFixedContainingBlock,
+                          nsContainerFrame*      aAbsoluteContainingBlock,
+                          nsContainerFrame*      aFloatContainingBlock,
+                          nsILayoutHistoryState* aHistoryState);
   // Get the history state from the pres context's pres shell.
   nsFrameConstructorState(nsIPresShell*          aPresShell,
                           nsContainerFrame*      aFixedContainingBlock,
                           nsContainerFrame*      aAbsoluteContainingBlock,
                           nsContainerFrame*      aFloatContainingBlock);
 
   ~nsFrameConstructorState();
 
@@ -915,53 +909,37 @@ protected:
 
   /**
    * ProcessFrameInsertions takes the frames in aFrameItems and adds them as
    * kids to the aChildListID child list of |aFrameItems.containingBlock|.
    */
   void ProcessFrameInsertions(nsAbsoluteItems& aFrameItems,
                               ChildListID aChildListID);
 
-  /**
-   * GetOutOfFlowFrameItems selects the out-of-flow frame list the new
-   * frame should be added to. If the frame shouldn't be added to any
-   * out-of-flow list, it returns nullptr. The corresponding type of
-   * placeholder is also returned via the aPlaceholderType parameter
-   * if this method doesn't return nullptr. The caller should check
-   * whether the returned list really has a containing block.
-   */
-  nsAbsoluteItems* GetOutOfFlowFrameItems(nsIFrame* aNewFrame,
-                                          bool aCanBePositioned,
-                                          bool aCanBeFloated,
-                                          bool aIsOutOfFlowPopup,
-                                          nsFrameState* aPlaceholderType);
-
   // Our list of all pending bindings.  When we're done, we need to call
   // AddToAttachedQueue on all of them, in order.
   LinkedList<PendingBinding> mPendingBindings;
 
   PendingBinding* mCurrentPendingBindingInsertionPoint;
 };
 
-nsFrameConstructorState::nsFrameConstructorState(
-  nsIPresShell* aPresShell,
-  nsContainerFrame* aFixedContainingBlock,
-  nsContainerFrame* aAbsoluteContainingBlock,
-  nsContainerFrame* aFloatContainingBlock,
-  already_AddRefed<nsILayoutHistoryState> aHistoryState)
+nsFrameConstructorState::nsFrameConstructorState(nsIPresShell*          aPresShell,
+                                                 nsContainerFrame*      aFixedContainingBlock,
+                                                 nsContainerFrame*      aAbsoluteContainingBlock,
+                                                 nsContainerFrame*      aFloatContainingBlock,
+                                                 nsILayoutHistoryState* aHistoryState)
   : mPresContext(aPresShell->GetPresContext()),
     mPresShell(aPresShell),
     mFrameManager(aPresShell->FrameManager()),
 #ifdef MOZ_XUL
     mPopupItems(nullptr),
 #endif
     mFixedItems(aFixedContainingBlock),
     mAbsoluteItems(aAbsoluteContainingBlock),
     mFloatedItems(aFloatContainingBlock),
-    mTopLayerItems(do_QueryFrame(mFrameManager->GetRootFrame())),
     // See PushAbsoluteContaningBlock below
     mFrameState(aHistoryState),
     mAdditionalStateBits(nsFrameState(0)),
     // If the fixed-pos containing block is equal to the abs-pos containing
     // block, use the abs-pos containing block's abs-pos list for fixed-pos
     // frames.
     mFixedPosIsAbsPos(aFixedContainingBlock == aAbsoluteContainingBlock),
     mHavePendingPopupgroup(false),
@@ -978,28 +956,50 @@ nsFrameConstructorState::nsFrameConstruc
 #endif
   MOZ_COUNT_CTOR(nsFrameConstructorState);
 }
 
 nsFrameConstructorState::nsFrameConstructorState(nsIPresShell* aPresShell,
                                                  nsContainerFrame* aFixedContainingBlock,
                                                  nsContainerFrame* aAbsoluteContainingBlock,
                                                  nsContainerFrame* aFloatContainingBlock)
-  : nsFrameConstructorState(aPresShell, aFixedContainingBlock,
-                            aAbsoluteContainingBlock,
-                            aFloatContainingBlock,
-                            aPresShell->GetDocument()->GetLayoutHistoryState())
-{
+  : mPresContext(aPresShell->GetPresContext()),
+    mPresShell(aPresShell),
+    mFrameManager(aPresShell->FrameManager()),
+#ifdef MOZ_XUL
+    mPopupItems(nullptr),
+#endif
+    mFixedItems(aFixedContainingBlock),
+    mAbsoluteItems(aAbsoluteContainingBlock),
+    mFloatedItems(aFloatContainingBlock),
+    // See PushAbsoluteContaningBlock below
+    mAdditionalStateBits(nsFrameState(0)),
+    // If the fixed-pos containing block is equal to the abs-pos containing
+    // block, use the abs-pos containing block's abs-pos list for fixed-pos
+    // frames.
+    mFixedPosIsAbsPos(aFixedContainingBlock == aAbsoluteContainingBlock),
+    mHavePendingPopupgroup(false),
+    mCreatingExtraFrames(false),
+    mTreeMatchContext(true, nsRuleWalker::eRelevantLinkUnvisited,
+                      aPresShell->GetDocument()),
+    mCurrentPendingBindingInsertionPoint(nullptr)
+{
+#ifdef MOZ_XUL
+  nsIRootBox* rootBox = nsIRootBox::GetRootBox(aPresShell);
+  if (rootBox) {
+    mPopupItems.containingBlock = rootBox->GetPopupSetFrame();
+  }
+#endif
+  MOZ_COUNT_CTOR(nsFrameConstructorState);
+  mFrameState = aPresShell->GetDocument()->GetLayoutHistoryState();
 }
 
 nsFrameConstructorState::~nsFrameConstructorState()
 {
   MOZ_COUNT_DTOR(nsFrameConstructorState);
-  // Items in the top layer are fixed positioned children of the viewport frame.
-  ProcessFrameInsertions(mTopLayerItems, nsIFrame::kFixedList);
   ProcessFrameInsertions(mFloatedItems, nsIFrame::kFloatList);
   ProcessFrameInsertions(mAbsoluteItems, nsIFrame::kAbsoluteList);
   ProcessFrameInsertions(mFixedItems, nsIFrame::kFixedList);
 #ifdef MOZ_XUL
   ProcessFrameInsertions(mPopupItems, nsIFrame::kPopupList);
 #endif
   for (int32_t i = mGeneratedTextNodesWithInitializer.Count() - 1; i >= 0; --i) {
     mGeneratedTextNodesWithInitializer[i]->
@@ -1105,108 +1105,90 @@ nsFrameConstructorState::GetGeometricPar
   }
 
   if (aStyleDisplay->IsFloatingStyle() && mFloatedItems.containingBlock) {
     NS_ASSERTION(!aStyleDisplay->IsAbsolutelyPositionedStyle(),
                  "Absolutely positioned _and_ floating?");
     return mFloatedItems.containingBlock;
   }
 
-  if (aStyleDisplay->mTopLayer != NS_STYLE_TOP_LAYER_NONE) {
-    MOZ_ASSERT(aStyleDisplay->mTopLayer == NS_STYLE_TOP_LAYER_TOP,
-               "-moz-top-layer should be either none or top");
-    MOZ_ASSERT(mTopLayerItems.containingBlock, "No root frame?");
-    MOZ_ASSERT(aStyleDisplay->IsAbsolutelyPositionedStyle(),
-               "Top layer items should always be absolutely positioned");
-    return mTopLayerItems.containingBlock;
-  }
-
   if (aStyleDisplay->mPosition == NS_STYLE_POSITION_ABSOLUTE &&
       mAbsoluteItems.containingBlock) {
     return mAbsoluteItems.containingBlock;
   }
 
   if (aStyleDisplay->mPosition == NS_STYLE_POSITION_FIXED &&
       GetFixedItems().containingBlock) {
     return GetFixedItems().containingBlock;
   }
 
   return aContentParentFrame;
 }
 
-nsAbsoluteItems*
-nsFrameConstructorState::GetOutOfFlowFrameItems(nsIFrame* aNewFrame,
-                                                bool aCanBePositioned,
-                                                bool aCanBeFloated,
-                                                bool aIsOutOfFlowPopup,
-                                                nsFrameState* aPlaceholderType)
-{
-#ifdef MOZ_XUL
-  if (MOZ_UNLIKELY(aIsOutOfFlowPopup)) {
-    MOZ_ASSERT(mPopupItems.containingBlock, "Must have a popup set frame!");
-    *aPlaceholderType = PLACEHOLDER_FOR_POPUP;
-    return &mPopupItems;
-  }
-#endif // MOZ_XUL
-  if (aCanBeFloated && aNewFrame->IsFloating()) {
-    *aPlaceholderType = PLACEHOLDER_FOR_FLOAT;
-    return &mFloatedItems;
-  }
-
-  if (aCanBePositioned) {
-    const nsStyleDisplay* disp = aNewFrame->StyleDisplay();
-    if (disp->mTopLayer != NS_STYLE_TOP_LAYER_NONE) {
-      *aPlaceholderType = PLACEHOLDER_FOR_FIXEDPOS;
-      return &mTopLayerItems;
-    }
-    if (disp->mPosition == NS_STYLE_POSITION_ABSOLUTE) {
-      *aPlaceholderType = PLACEHOLDER_FOR_ABSPOS;
-      return &mAbsoluteItems;
-    }
-    if (disp->mPosition == NS_STYLE_POSITION_FIXED) {
-      *aPlaceholderType = PLACEHOLDER_FOR_FIXEDPOS;
-      return &GetFixedItems();
-    }
-  }
-  return nullptr;
-}
-
 void
 nsFrameConstructorState::AddChild(nsIFrame* aNewFrame,
                                   nsFrameItems& aFrameItems,
                                   nsIContent* aContent,
                                   nsStyleContext* aStyleContext,
                                   nsContainerFrame* aParentFrame,
                                   bool aCanBePositioned,
                                   bool aCanBeFloated,
                                   bool aIsOutOfFlowPopup,
                                   bool aInsertAfter,
                                   nsIFrame* aInsertAfterFrame)
 {
   NS_PRECONDITION(!aNewFrame->GetNextSibling(), "Shouldn't happen");
 
-  nsFrameState placeholderType;
-  nsAbsoluteItems* outOfFlowFrameItems =
-    GetOutOfFlowFrameItems(aNewFrame, aCanBePositioned, aCanBeFloated,
-                           aIsOutOfFlowPopup, &placeholderType);
+  const nsStyleDisplay* disp = aNewFrame->StyleDisplay();
 
   // The comments in GetGeometricParent regarding root table frames
-  // all apply here, unfortunately. Thus, we need to check whether
-  // the returned frame items really has containing block.
-  nsFrameItems* frameItems;
-  if (outOfFlowFrameItems && outOfFlowFrameItems->containingBlock) {
-    MOZ_ASSERT(aNewFrame->GetParent() == outOfFlowFrameItems->containingBlock,
-               "Parent of the frame is not the containing block?");
-    frameItems = outOfFlowFrameItems;
-  } else {
-    frameItems = &aFrameItems;
-    placeholderType = nsFrameState(0);
-  }
-
-  if (placeholderType) {
+  // all apply here, unfortunately.
+
+  bool needPlaceholder = false;
+  nsFrameState placeholderType;
+  nsFrameItems* frameItems = &aFrameItems;
+#ifdef MOZ_XUL
+  if (MOZ_UNLIKELY(aIsOutOfFlowPopup)) {
+      NS_ASSERTION(aNewFrame->GetParent() == mPopupItems.containingBlock,
+                   "Popup whose parent is not the popup containing block?");
+      NS_ASSERTION(mPopupItems.containingBlock, "Must have a popup set frame!");
+      needPlaceholder = true;
+      frameItems = &mPopupItems;
+      placeholderType = PLACEHOLDER_FOR_POPUP;
+  }
+  else
+#endif // MOZ_XUL
+  if (aCanBeFloated && aNewFrame->IsFloating() &&
+      mFloatedItems.containingBlock) {
+    NS_ASSERTION(aNewFrame->GetParent() == mFloatedItems.containingBlock,
+                 "Float whose parent is not the float containing block?");
+    needPlaceholder = true;
+    frameItems = &mFloatedItems;
+    placeholderType = PLACEHOLDER_FOR_FLOAT;
+  }
+  else if (aCanBePositioned) {
+    if (disp->mPosition == NS_STYLE_POSITION_ABSOLUTE &&
+        mAbsoluteItems.containingBlock) {
+      NS_ASSERTION(aNewFrame->GetParent() == mAbsoluteItems.containingBlock,
+                   "Abs pos whose parent is not the abs pos containing block?");
+      needPlaceholder = true;
+      frameItems = &mAbsoluteItems;
+      placeholderType = PLACEHOLDER_FOR_ABSPOS;
+    }
+    if (disp->mPosition == NS_STYLE_POSITION_FIXED &&
+        GetFixedItems().containingBlock) {
+      NS_ASSERTION(aNewFrame->GetParent() == GetFixedItems().containingBlock,
+                   "Fixed pos whose parent is not the fixed pos containing block?");
+      needPlaceholder = true;
+      frameItems = &GetFixedItems();
+      placeholderType = PLACEHOLDER_FOR_FIXEDPOS;
+    }
+  }
+
+  if (needPlaceholder) {
     NS_ASSERTION(frameItems != &aFrameItems,
                  "Putting frame in-flow _and_ want a placeholder?");
     nsIFrame* placeholderFrame =
       nsCSSFrameConstructor::CreatePlaceholderFrameFor(mPresShell,
                                                        aContent,
                                                        aNewFrame,
                                                        aStyleContext,
                                                        aParentFrame,
@@ -1234,18 +1216,17 @@ nsFrameConstructorState::AddChild(nsIFra
 void
 nsFrameConstructorState::ProcessFrameInsertions(nsAbsoluteItems& aFrameItems,
                                                 ChildListID aChildListID)
 {
 #define NS_NONXUL_LIST_TEST (&aFrameItems == &mFloatedItems &&            \
                              aChildListID == nsIFrame::kFloatList)    ||  \
                             (&aFrameItems == &mAbsoluteItems &&           \
                              aChildListID == nsIFrame::kAbsoluteList) ||  \
-                            ((&aFrameItems == &mFixedItems ||             \
-                              &aFrameItems == &mTopLayerItems) &&         \
+                            (&aFrameItems == &mFixedItems &&              \
                              aChildListID == nsIFrame::kFixedList)
 #ifdef MOZ_XUL
   NS_PRECONDITION(NS_NONXUL_LIST_TEST ||
                   (&aFrameItems == &mPopupItems &&
                    aChildListID == nsIFrame::kPopupList),
                   "Unexpected aFrameItems/aChildListID combination");
 #else
   NS_PRECONDITION(NS_NONXUL_LIST_TEST,
@@ -2336,17 +2317,17 @@ nsCSSFrameConstructor::ConstructDocEleme
 
   SetUpDocElementContainingBlock(aDocElement);
 
   NS_ASSERTION(mDocElementContainingBlock, "Should have parent by now");
 
   nsFrameConstructorState state(mPresShell,
                                 GetAbsoluteContainingBlock(mDocElementContainingBlock, FIXED_POS),
                                 nullptr,
-                                nullptr, do_AddRef(Move(aFrameState)));
+                                nullptr, aFrameState);
   // Initialize the ancestor filter with null for now; we'll push
   // aDocElement once we finish resolving style for it.
   state.mTreeMatchContext.InitAncestors(nullptr);
 
   // XXXbz why, exactly?
   if (!mTempFrameTreeState)
     state.mPresShell->CaptureHistoryState(getter_AddRefs(mTempFrameTreeState));
 
@@ -7562,17 +7543,17 @@ nsCSSFrameConstructor::ContentRangeInser
     LAYOUT_PHASE_TEMP_REENTER();
     return rv;
   }
 
   nsFrameConstructorState state(mPresShell,
                                 GetAbsoluteContainingBlock(insertion.mParentFrame, FIXED_POS),
                                 GetAbsoluteContainingBlock(insertion.mParentFrame, ABS_POS),
                                 GetFloatContainingBlock(insertion.mParentFrame),
-                                do_AddRef(Move(aFrameState)));
+                                aFrameState);
   state.mTreeMatchContext.InitAncestors(aContainer ?
                                           aContainer->AsElement() :
                                           nullptr);
 
   // Recover state for the containing block - we need to know if
   // it has :first-letter or :first-line style applied to it. The
   // reason we care is that the internal structure in these cases
   // is not the normal structure and requires custom updating
@@ -11278,17 +11259,17 @@ nsCSSFrameConstructor::CreateListBoxCont
   nsresult rv = NS_OK;
 
   // Construct a new frame
   if (nullptr != aParentFrame) {
     nsFrameItems            frameItems;
     nsFrameConstructorState state(mPresShell, GetAbsoluteContainingBlock(aParentFrame, FIXED_POS),
                                   GetAbsoluteContainingBlock(aParentFrame, ABS_POS),
                                   GetFloatContainingBlock(aParentFrame),
-                                  do_AddRef(mTempFrameTreeState.get()));
+                                  mTempFrameTreeState);
 
     // If we ever initialize the ancestor filter on |state|, make sure
     // to push the right parent!
 
     nsRefPtr<nsStyleContext> styleContext;
     styleContext = ResolveStyleContext(aParentFrame, aChild, &state);
 
     // Pre-check for display "none" - only if we find that, do we create
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -859,23 +859,16 @@ public:
       : mDirtyRect(aDirtyRect)
     {}
     DisplayItemClip mContainingBlockClip;
     nsRect mDirtyRect;
   };
 
   NS_DECLARE_FRAME_PROPERTY(OutOfFlowDisplayDataProperty,
                             DeleteValue<OutOfFlowDisplayData>)
-
-  static OutOfFlowDisplayData* GetOutOfFlowData(nsIFrame* aFrame)
-  {
-    return static_cast<OutOfFlowDisplayData*>(
-      aFrame->Properties().Get(OutOfFlowDisplayDataProperty()));
-  }
-
   NS_DECLARE_FRAME_PROPERTY(Preserve3DDirtyRectProperty, DeleteValue<nsRect>)
 
   nsPresContext* CurrentPresContext() {
     return CurrentPresShellState()->mPresShell->GetPresContext();
   }
 
   /**
    * Accumulates the bounds of box frames that have moz-appearance
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -2234,16 +2234,21 @@ nsDocumentViewer::CreateStyleSet(nsIDocu
 
   if (!shouldOverride) {
     sheet = nsLayoutStylesheetCache::ScrollbarsSheet();
     if (sheet) {
       styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
     }
   }
 
+  sheet = nsLayoutStylesheetCache::FullScreenOverrideSheet();
+  if (sheet) {
+    styleSet->PrependStyleSheet(nsStyleSet::eOverrideSheet, sheet);
+  }
+
   if (!aDocument->IsSVGDocument()) {
     // !!! IMPORTANT - KEEP THIS BLOCK IN SYNC WITH
     // !!! SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded.
 
     // SVGForeignObjectElement::BindToTree calls SVGDocument::
     // EnsureNonSVGUserAgentStyleSheetsLoaded to loads these UA sheet
     // on-demand. (Excluding the quirks sheet, which should never be loaded for
     // an SVG document, and excluding xul.css which will be loaded on demand by
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2309,49 +2309,37 @@ nsIFrame::BuildDisplayListForChild(nsDis
     // it acts like inline-block or inline-table. Therefore it is a
     // pseudo-stacking-context.
     pseudoStackingContext = true;
   }
 
   // dirty rect in child-relative coordinates
   nsRect dirty = aDirtyRect - child->GetOffsetTo(this);
 
-  const nsStyleDisplay* disp;
   nsIAtom* childType = child->GetType();
   nsDisplayListBuilder::OutOfFlowDisplayData* savedOutOfFlowData = nullptr;
-  if (childType != nsGkAtoms::placeholderFrame) {
-    disp = child->StyleDisplay();
-  } else {
+  if (childType == nsGkAtoms::placeholderFrame) {
     nsPlaceholderFrame* placeholder = static_cast<nsPlaceholderFrame*>(child);
     child = placeholder->GetOutOfFlowFrame();
     NS_ASSERTION(child, "No out of flow frame?");
     // If 'child' is a pushed float then it's owned by a block that's not an
     // ancestor of the placeholder, and it will be painted by that block and
     // should not be painted through the placeholder.
     if (!child || nsLayoutUtils::IsPopup(child) ||
         (child->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT))
       return;
-    MOZ_ASSERT(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW);
-    disp = child->StyleDisplay();
-    // If the out-of-flow frame is in the top layer, the viewport frame
-    // will paint it. Skip it here. Note that, only out-of-flow frames
-    // with this property should be skipped, because non-HTML elements
-    // may stop their children from being out-of-flow. Those frames
-    // should still be handled in the normal in-flow path.
-    if (disp->mTopLayer != NS_STYLE_TOP_LAYER_NONE) {
-      return;
-    }
     // Make sure that any attempt to use childType below is disappointed. We
     // could call GetType again but since we don't currently need it, let's
     // avoid the virtual call.
     childType = nullptr;
     // Recheck NS_FRAME_TOO_DEEP_IN_FRAME_TREE
     if (child->GetStateBits() & NS_FRAME_TOO_DEEP_IN_FRAME_TREE)
       return;
-    savedOutOfFlowData = nsDisplayListBuilder::GetOutOfFlowData(child);
+    savedOutOfFlowData = static_cast<nsDisplayListBuilder::OutOfFlowDisplayData*>
+      (child->Properties().Get(nsDisplayListBuilder::OutOfFlowDisplayDataProperty()));
     if (savedOutOfFlowData) {
       dirty = savedOutOfFlowData->mDirtyRect;
     } else {
       // The out-of-flow frame did not intersect the dirty area. We may still
       // need to traverse into it, since it may contain placeholders we need
       // to enter to reach other out-of-flow frames that are visible.
       dirty.SetEmpty();
     }
@@ -2411,16 +2399,17 @@ nsIFrame::BuildDisplayListForChild(nsDis
   // REVIEW: Taken from nsBoxFrame::Paint
   // Don't paint our children if the theme object is a leaf.
   if (IsThemed(ourDisp) &&
       !PresContext()->GetTheme()->WidgetIsContainer(ourDisp->mAppearance))
     return;
 
   // Child is composited if it's transformed, partially transparent, or has
   // SVG effects or a blend mode..
+  const nsStyleDisplay* disp = child->StyleDisplay();
   const nsStylePosition* pos = child->StylePosition();
   bool isVisuallyAtomic = child->HasOpacity()
     || child->IsTransformed()
     // strictly speaking, 'perspective' doesn't require visual atomicity,
     // but the spec says it acts like the rest of these
     || disp->mChildPerspective.GetUnit() == eStyleUnit_Coord
     || disp->mMixBlendMode != NS_STYLE_BLEND_NORMAL
     || nsSVGIntegrationUtils::UsingEffectsForFrame(child)
--- a/layout/generic/nsViewportFrame.cpp
+++ b/layout/generic/nsViewportFrame.cpp
@@ -46,77 +46,24 @@ ViewportFrame::Init(nsIContent*       aC
 void
 ViewportFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists)
 {
   PROFILER_LABEL("ViewportFrame", "BuildDisplayList",
     js::ProfileEntry::Category::GRAPHICS);
 
-  if (nsIFrame* kid = mFrames.FirstChild()) {
-    // make the kid's BorderBackground our own. This ensures that the canvas
-    // frame's background becomes our own background and therefore appears
-    // below negative z-index elements.
-    BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
-  }
-
-  nsDisplayList topLayerList;
-  BuildDisplayListForTopLayer(aBuilder, &topLayerList);
-  if (!topLayerList.IsEmpty()) {
-    // Wrap the whole top layer in a single item with maximum z-index,
-    // and append it at the very end, so that it stays at the topmost.
-    nsDisplayWrapList* wrapList =
-      new (aBuilder) nsDisplayWrapList(aBuilder, this, &topLayerList);
-    wrapList->SetOverrideZIndex(
-      std::numeric_limits<decltype(wrapList->ZIndex())>::max());
-    aLists.PositionedDescendants()->AppendNewToTop(wrapList);
-  }
-}
+  nsIFrame* kid = mFrames.FirstChild();
+  if (!kid)
+    return;
 
-void
-ViewportFrame::BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder,
-                                           nsDisplayList* aList)
-{
-  nsIDocument* doc = PresContext()->Document();
-  nsTArray<Element*> fullscreenStack = doc->GetFullscreenStack();
-  for (Element* elem : fullscreenStack) {
-    // Root element cannot be put in the top layer.
-    if (!elem->GetParent()) {
-      continue;
-    }
-    if (nsIFrame* frame = elem->GetPrimaryFrame()) {
-      // When building display list for purpose other than painting, it
-      // is possible that the style and layout info is inconsistent with
-      // the content tree. Skip inconsistent frames in that case.
-      if (frame->StyleDisplay()->mTopLayer == NS_STYLE_TOP_LAYER_NONE) {
-        MOZ_ASSERT(!aBuilder->IsForPainting(), "Fullscreen element should "
-                   "always be in the top layer for painting");
-        continue;
-      }
-      // Inner SVG, MathML elements, as well as children of some XUL
-      // elements are not allowed to be out-of-flow. They should not
-      // be handled as top layer element here.
-      if (!(frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
-        MOZ_ASSERT(!elem->GetParent()->IsHTMLElement(), "HTML element "
-                   "should always be out-of-flow if in the top layer");
-        continue;
-      }
-      MOZ_ASSERT(frame->GetParent() == this);
-
-      nsRect dirty;
-      nsDisplayListBuilder::OutOfFlowDisplayData*
-        savedOutOfFlowData = nsDisplayListBuilder::GetOutOfFlowData(frame);
-      if (savedOutOfFlowData) {
-        dirty = savedOutOfFlowData->mDirtyRect;
-      }
-      nsDisplayList list;
-      frame->BuildDisplayListForStackingContext(aBuilder, dirty, &list);
-      aList->AppendToTop(&list);
-    }
-  }
+  // make the kid's BorderBackground our own. This ensures that the canvas
+  // frame's background becomes our own background and therefore appears
+  // below negative z-index elements.
+  BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
 }
 
 #ifdef DEBUG
 void
 ViewportFrame::SetInitialChildList(ChildListID     aListID,
                                    nsFrameList&    aChildList)
 {
   nsFrame::VerifyDirtyBitSet(aChildList);
--- a/layout/generic/nsViewportFrame.h
+++ b/layout/generic/nsViewportFrame.h
@@ -58,19 +58,16 @@ public:
   virtual void RemoveFrame(ChildListID     aListID,
                            nsIFrame*       aOldFrame) override;
 #endif
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) override;
 
-  void BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder,
-                                   nsDisplayList* aList);
-
   virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override;
   virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override;
   virtual void Reflow(nsPresContext*           aPresContext,
                       nsHTMLReflowMetrics&     aDesiredSize,
                       const nsHTMLReflowState& aReflowState,
                       nsReflowStatus&          aStatus) override;
 
   /**
new file mode 100644
--- /dev/null
+++ b/layout/style/full-screen-override.css
@@ -0,0 +1,26 @@
+/* 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/. */
+
+
+*|*:-moz-full-screen-ancestor {
+  /* Ancestors of a full-screen element should not induce stacking contexts
+     that would prevent the full-screen element from being on top. */
+  z-index: initial !important;
+  /* Ancestors of a full-screen element should not be partially transparent,
+     since that would apply to the full-screen element and make the page visible
+     behind it. It would also create a pseudo-stacking-context that would let content
+     draw on top of the full-screen element. */
+  opacity: initial !important;
+  /* Ancestors of a full-screen element should not apply SVG masking, clipping, or
+     filtering, since that would affect the full-screen element and create a pseudo-
+     stacking context. */
+  mask: initial !important;
+  clip-path: initial !important;
+  filter: initial !important;
+  clip: initial !important;
+  transform: initial !important;
+  transform-style: initial !important;
+  /* FIXME: do we need to worry about 'overflow'? */
+  will-change: initial !important;
+}
--- a/layout/style/jar.mn
+++ b/layout/style/jar.mn
@@ -1,16 +1,17 @@
 # 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/.
 
 toolkit.jar:
 *  res/ua.css    (ua.css)
 *  res/html.css    (html.css)
    res/quirk.css    (quirk.css)
+   res/full-screen-override.css    (full-screen-override.css)
    res/plaintext.css     (plaintext.css)
    res/viewsource.css    (viewsource.css)
    res/counterstyles.css (counterstyles.css)
    res/noscript.css (noscript.css)
    res/noframes.css (noframes.css)
 *  res/forms.css    (forms.css)
    res/number-control.css    (number-control.css)
    res/arrow.gif        (arrow.gif)
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -3409,31 +3409,17 @@ CSS_PROP_POSITION(
         CSS_PROPERTY_STORES_CALC |
         CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
         CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH,
     "",
     VARIANT_AHLP | VARIANT_CALC,
     nullptr,
     offsetof(nsStylePosition, mOffset),
     eStyleAnimType_Sides_Top)
-#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
-CSS_PROP_DISPLAY(
-    -moz-top-layer,
-    _moz_top_layer,
-    CSS_PROP_DOMPROP_PREFIXED(TopLayer),
-    CSS_PROPERTY_INTERNAL |
-        CSS_PROPERTY_PARSE_VALUE |
-        CSS_PROPERTY_ENABLED_IN_UA_SHEETS,
-    "",
-    VARIANT_HK,
-    kTopLayerKTable,
-    CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
-#endif // CSS_PROP_LIST_EXCLUDE_INTERNAL
-CSS_PROP_DISPLAY(
+ CSS_PROP_DISPLAY(
     touch-action,
     touch_action,
     TouchAction,
     CSS_PROPERTY_PARSE_VALUE |
         CSS_PROPERTY_VALUE_PARSER_FUNCTION,
     "layout.css.touch_action.enabled",
     VARIANT_HK,
     kTouchActionKTable,
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -1829,22 +1829,16 @@ const KTableValue nsCSSProps::kTouchActi
   eCSSKeyword_none,         NS_STYLE_TOUCH_ACTION_NONE,
   eCSSKeyword_auto,         NS_STYLE_TOUCH_ACTION_AUTO,
   eCSSKeyword_pan_x,        NS_STYLE_TOUCH_ACTION_PAN_X,
   eCSSKeyword_pan_y,        NS_STYLE_TOUCH_ACTION_PAN_Y,
   eCSSKeyword_manipulation, NS_STYLE_TOUCH_ACTION_MANIPULATION,
   eCSSKeyword_UNKNOWN,      -1
 };
 
-const KTableValue nsCSSProps::kTopLayerKTable[] = {
-  eCSSKeyword_none,     NS_STYLE_TOP_LAYER_NONE,
-  eCSSKeyword_top,      NS_STYLE_TOP_LAYER_TOP,
-  eCSSKeyword_UNKNOWN,  -1
-};
-
 const KTableValue nsCSSProps::kTransformBoxKTable[] = {
   eCSSKeyword_border_box, NS_STYLE_TRANSFORM_BOX_BORDER_BOX,
   eCSSKeyword_fill_box, NS_STYLE_TRANSFORM_BOX_FILL_BOX,
   eCSSKeyword_view_box, NS_STYLE_TRANSFORM_BOX_VIEW_BOX,
   eCSSKeyword_UNKNOWN,-1
 };
 
 const KTableValue nsCSSProps::kTransitionTimingFunctionKTable[] = {
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -745,17 +745,16 @@ public:
   static KTableValue kTextAlignLastKTable[];
   static const KTableValue kTextCombineUprightKTable[];
   static const KTableValue kTextDecorationLineKTable[];
   static const KTableValue kTextDecorationStyleKTable[];
   static const KTableValue kTextOrientationKTable[];
   static const KTableValue kTextOverflowKTable[];
   static const KTableValue kTextTransformKTable[];
   static const KTableValue kTouchActionKTable[];
-  static const KTableValue kTopLayerKTable[];
   static const KTableValue kTransformBoxKTable[];
   static const KTableValue kTransitionTimingFunctionKTable[];
   static const KTableValue kUnicodeBidiKTable[];
   static const KTableValue kUserFocusKTable[];
   static const KTableValue kUserInputKTable[];
   static const KTableValue kUserModifyKTable[];
   static const KTableValue kUserSelectKTable[];
   static const KTableValue kVerticalAlignKTable[];
--- a/layout/style/nsLayoutStylesheetCache.cpp
+++ b/layout/style/nsLayoutStylesheetCache.cpp
@@ -153,16 +153,23 @@ nsLayoutStylesheetCache::XULSheet()
 CSSStyleSheet*
 nsLayoutStylesheetCache::QuirkSheet()
 {
   EnsureGlobal();
   return gStyleCache->mQuirkSheet;
 }
 
 CSSStyleSheet*
+nsLayoutStylesheetCache::FullScreenOverrideSheet()
+{
+  EnsureGlobal();
+  return gStyleCache->mFullScreenOverrideSheet;
+}
+
+CSSStyleSheet*
 nsLayoutStylesheetCache::SVGSheet()
 {
   EnsureGlobal();
   return gStyleCache->mSVGSheet;
 }
 
 CSSStyleSheet*
 nsLayoutStylesheetCache::MathMLSheet()
@@ -304,16 +311,17 @@ nsLayoutStylesheetCache::SizeOfIncluding
   #define MEASURE(s) n += s ? s->SizeOfIncludingThis(aMallocSizeOf) : 0;
 
   MEASURE(mChromePreferenceSheet);
   MEASURE(mContentEditableSheet);
   MEASURE(mContentPreferenceSheet);
   MEASURE(mCounterStylesSheet);
   MEASURE(mDesignModeSheet);
   MEASURE(mFormsSheet);
+  MEASURE(mFullScreenOverrideSheet);
   MEASURE(mHTMLSheet);
   MEASURE(mMathMLSheet);
   MEASURE(mMinimalXULSheet);
   MEASURE(mNoFramesSheet);
   MEASURE(mNoScriptSheet);
   MEASURE(mNumberControlSheet);
   MEASURE(mQuirkSheet);
   MEASURE(mSVGSheet);
@@ -344,16 +352,18 @@ nsLayoutStylesheetCache::nsLayoutStylesh
   }
 
   InitFromProfile();
 
   // And make sure that we load our UA sheets.  No need to do this
   // per-profile, since they're profile-invariant.
   LoadSheetURL("resource://gre-resources/counterstyles.css",
                mCounterStylesSheet, true);
+  LoadSheetURL("resource://gre-resources/full-screen-override.css",
+               mFullScreenOverrideSheet, true);
   LoadSheetURL("chrome://global/content/minimal-xul.css",
                mMinimalXULSheet, true);
   LoadSheetURL("resource://gre-resources/quirk.css",
                mQuirkSheet, true);
   LoadSheetURL("resource://gre/res/svg.css",
                mSVGSheet, true);
   LoadSheetURL("chrome://global/content/xul.css",
                mXULSheet, true);
--- a/layout/style/nsLayoutStylesheetCache.h
+++ b/layout/style/nsLayoutStylesheetCache.h
@@ -39,16 +39,17 @@ class nsLayoutStylesheetCache final
   static mozilla::CSSStyleSheet* NumberControlSheet();
   static mozilla::CSSStyleSheet* UserContentSheet();
   static mozilla::CSSStyleSheet* UserChromeSheet();
   static mozilla::CSSStyleSheet* UASheet();
   static mozilla::CSSStyleSheet* HTMLSheet();
   static mozilla::CSSStyleSheet* MinimalXULSheet();
   static mozilla::CSSStyleSheet* XULSheet();
   static mozilla::CSSStyleSheet* QuirkSheet();
+  static mozilla::CSSStyleSheet* FullScreenOverrideSheet();
   static mozilla::CSSStyleSheet* SVGSheet();
   static mozilla::CSSStyleSheet* MathMLSheet();
   static mozilla::CSSStyleSheet* CounterStylesSheet();
   static mozilla::CSSStyleSheet* NoScriptSheet();
   static mozilla::CSSStyleSheet* NoFramesSheet();
   static mozilla::CSSStyleSheet* ChromePreferenceSheet(nsPresContext* aPresContext);
   static mozilla::CSSStyleSheet* ContentPreferenceSheet(nsPresContext* aPresContext);
   static mozilla::CSSStyleSheet* ContentEditableSheet();
@@ -86,16 +87,17 @@ private:
   static mozilla::StaticRefPtr<nsLayoutStylesheetCache> gStyleCache;
   static mozilla::css::Loader* gCSSLoader;
   nsRefPtr<mozilla::CSSStyleSheet> mChromePreferenceSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mContentEditableSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mContentPreferenceSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mCounterStylesSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mDesignModeSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mFormsSheet;
+  nsRefPtr<mozilla::CSSStyleSheet> mFullScreenOverrideSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mHTMLSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mMathMLSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mMinimalXULSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mNoFramesSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mNoScriptSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mNumberControlSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mQuirkSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mSVGSheet;
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -5441,23 +5441,16 @@ nsRuleNode::ComputeDisplayData(void* aSt
 
   // isolation: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForIsolation(), display->mIsolation,
               conditions,
               SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
               parentDisplay->mIsolation, NS_STYLE_ISOLATION_AUTO,
               0, 0, 0, 0);
 
-  // -moz-top-layer: enum, inherit, initial
-  SetDiscrete(*aRuleData->ValueForTopLayer(), display->mTopLayer,
-              conditions,
-              SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
-              parentDisplay->mTopLayer, NS_STYLE_TOP_LAYER_NONE,
-              0, 0, 0, 0);
-
   // Backup original display value for calculation of a hypothetical
   // box (CSS2 10.6.4/10.6.5), in addition to getting our style data right later.
   // See nsHTMLReflowState::CalculateHypotheticalBox
   display->mOriginalDisplay = display->mDisplay;
 
   // appearance: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForAppearance(),
               display->mAppearance, conditions,
@@ -5487,26 +5480,16 @@ nsRuleNode::ComputeDisplayData(void* aSt
     display->mBinding = parentDisplay->mBinding;
   }
 
   // position: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForPosition(), display->mPosition, conditions,
               SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
               parentDisplay->mPosition,
               NS_STYLE_POSITION_STATIC, 0, 0, 0, 0);
-  // If an element is put in the top layer, while it is not absolutely
-  // positioned, the position value should be computed to 'absolute' per
-  // the Fullscreen API spec.
-  if (display->mTopLayer != NS_STYLE_TOP_LAYER_NONE &&
-      !display->IsAbsolutelyPositionedStyle()) {
-    display->mPosition = NS_STYLE_POSITION_ABSOLUTE;
-    // We cannot cache this struct because otherwise it may be used as
-    // an aStartStruct for some other elements.
-    conditions.SetUncacheable();
-  }
 
   // clear: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForClear(), display->mBreakType, conditions,
               SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
               parentDisplay->mBreakType,
               NS_STYLE_CLEAR_NONE, 0, 0, 0, 0);
 
   // temp fix for bug 24000
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -812,20 +812,16 @@ static inline mozilla::css::Side operato
 // See nsStyleDisplay
 #define NS_STYLE_TOUCH_ACTION_NONE            (1 << 0)
 #define NS_STYLE_TOUCH_ACTION_AUTO            (1 << 1)
 #define NS_STYLE_TOUCH_ACTION_PAN_X           (1 << 2)
 #define NS_STYLE_TOUCH_ACTION_PAN_Y           (1 << 3)
 #define NS_STYLE_TOUCH_ACTION_MANIPULATION    (1 << 4)
 
 // See nsStyleDisplay
-#define NS_STYLE_TOP_LAYER_NONE   0 // not in the top layer
-#define NS_STYLE_TOP_LAYER_TOP    1 // in the top layer
-
-// See nsStyleDisplay
 #define NS_STYLE_TRANSFORM_BOX_BORDER_BOX                0
 #define NS_STYLE_TRANSFORM_BOX_FILL_BOX                  1
 #define NS_STYLE_TRANSFORM_BOX_VIEW_BOX                  2
 
 // See nsStyleDisplay
 #define NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE         0
 #define NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR       1
 #define NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN      2
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2624,17 +2624,16 @@ nsStyleDisplay::nsStyleDisplay()
   mChildPerspective.SetNoneValue();
   mBackfaceVisibility = NS_STYLE_BACKFACE_VISIBILITY_VISIBLE;
   mTransformStyle = NS_STYLE_TRANSFORM_STYLE_FLAT;
   mTransformBox = NS_STYLE_TRANSFORM_BOX_BORDER_BOX;
   mOrient = NS_STYLE_ORIENT_INLINE;
   mMixBlendMode = NS_STYLE_BLEND_NORMAL;
   mIsolation = NS_STYLE_ISOLATION_AUTO;
   mTouchAction = NS_STYLE_TOUCH_ACTION_AUTO;
-  mTopLayer = NS_STYLE_TOP_LAYER_NONE;
   mScrollBehavior = NS_STYLE_SCROLL_BEHAVIOR_AUTO;
   mScrollSnapTypeX = NS_STYLE_SCROLL_SNAP_TYPE_NONE;
   mScrollSnapTypeY = NS_STYLE_SCROLL_SNAP_TYPE_NONE;
   mScrollSnapPointsX.SetNoneValue();
   mScrollSnapPointsY.SetNoneValue();
   // Initial value for mScrollSnapDestination is "0px 0px"
   mScrollSnapDestination.SetInitialZeroValues();
 
@@ -2679,17 +2678,16 @@ nsStyleDisplay::nsStyleDisplay(const nsS
   , mOverflowX(aSource.mOverflowX)
   , mOverflowY(aSource.mOverflowY)
   , mOverflowClipBox(aSource.mOverflowClipBox)
   , mResize(aSource.mResize)
   , mClipFlags(aSource.mClipFlags)
   , mOrient(aSource.mOrient)
   , mMixBlendMode(aSource.mMixBlendMode)
   , mIsolation(aSource.mIsolation)
-  , mTopLayer(aSource.mTopLayer)
   , mWillChangeBitField(aSource.mWillChangeBitField)
   , mWillChange(aSource.mWillChange)
   , mTouchAction(aSource.mTouchAction)
   , mScrollBehavior(aSource.mScrollBehavior)
   , mScrollSnapTypeX(aSource.mScrollSnapTypeX)
   , mScrollSnapTypeY(aSource.mScrollSnapTypeY)
   , mScrollSnapPointsX(aSource.mScrollSnapPointsX)
   , mScrollSnapPointsY(aSource.mScrollSnapPointsY)
@@ -2737,17 +2735,16 @@ nsChangeHint nsStyleDisplay::CalcDiffere
       || mOverflowX != aOther.mOverflowX
       || mOverflowY != aOther.mOverflowY
       || mScrollBehavior != aOther.mScrollBehavior
       || mScrollSnapTypeX != aOther.mScrollSnapTypeX
       || mScrollSnapTypeY != aOther.mScrollSnapTypeY
       || mScrollSnapPointsX != aOther.mScrollSnapPointsX
       || mScrollSnapPointsY != aOther.mScrollSnapPointsY
       || mScrollSnapDestination != aOther.mScrollSnapDestination
-      || mTopLayer != aOther.mTopLayer
       || mResize != aOther.mResize)
     NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
 
   /* Note: When mScrollBehavior, mScrollSnapTypeX, mScrollSnapTypeY,
    * mScrollSnapPointsX, mScrollSnapPointsY, or mScrollSnapDestination are
    * changed, nsChangeHint_NeutralChange is not sufficient to enter
    * nsCSSFrameConstructor::PropagateScrollToViewport. By using the same hint
    * as used when the overflow css property changes,
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2161,17 +2161,16 @@ struct nsStyleDisplay {
   uint8_t mOverflowX;           // [reset] see nsStyleConsts.h
   uint8_t mOverflowY;           // [reset] see nsStyleConsts.h
   uint8_t mOverflowClipBox;     // [reset] see nsStyleConsts.h
   uint8_t mResize;              // [reset] see nsStyleConsts.h
   uint8_t mClipFlags;           // [reset] see nsStyleConsts.h
   uint8_t mOrient;              // [reset] see nsStyleConsts.h
   uint8_t mMixBlendMode;        // [reset] see nsStyleConsts.h
   uint8_t mIsolation;           // [reset] see nsStyleConsts.h
-  uint8_t mTopLayer;            // [reset] see nsStyleConsts.h
   uint8_t mWillChangeBitField;  // [reset] see nsStyleConsts.h. Stores a
                                 // bitfield representation of the properties
                                 // that are frequently queried. This should
                                 // match mWillChange. Also tracks if any of the
                                 // properties in the will-change list require
                                 // a stacking context.
   nsAutoTArray<nsString, 1> mWillChange;
 
--- a/layout/style/ua.css
+++ b/layout/style/ua.css
@@ -258,17 +258,16 @@
 
   * {
     cursor: default !important;
   }
 
 }
 
 *|*:not(:root):-moz-full-screen {
-  -moz-top-layer: top !important;
   position: fixed !important;
   top: 0 !important;
   left: 0 !important;
   right: 0 !important;
   bottom: 0 !important;
   z-index: 2147483647 !important;
   background: black;
   width: 100% !important;