Bug 1449791 - Remove platform support of overlays. r=bz
authorBrendan Dahl <brendan.dahl@gmail.com>
Wed, 28 Mar 2018 18:20:04 -0700
changeset 467175 5f50dd0905ec23b0d1fa1747905d5a1ef5f73dc2
parent 467174 9e0a8856d71a2a1107c4cd23468c2e3171ede8df
child 467176 7d3fe27beec58d201a98d6bfcbe43d6e493348c6
push idunknown
push userunknown
push dateunknown
reviewersbz
bugs1449791
milestone63.0a1
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
Bug 1449791 - Remove platform support of overlays. r=bz The following was removed: - the main meat of the overlays and interface in XULDocument - all overlay observers and forward references - the notion of a master document - XUL overlay provider - manifest parsing of overlay attribute - references to "overlay" atom - restrictions on persistence (only need because of overlays) - unused code that the above referenced I also attempted to update comments that referenced overlays, but there is still some work to be done here. MozReview-Commit-ID: 8lrirzcgSuJ
chrome/nsChromeRegistry.cpp
chrome/nsChromeRegistry.h
chrome/nsChromeRegistryChrome.cpp
chrome/nsChromeRegistryChrome.h
chrome/nsChromeRegistryContent.cpp
chrome/nsChromeRegistryContent.h
dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/gecko_dom.js
dom/webidl/XULDocument.webidl
dom/xul/XULDocument.cpp
dom/xul/XULDocument.h
dom/xul/XULFrameElement.cpp
dom/xul/moz.build
dom/xul/nsIXULOverlayProvider.idl
dom/xul/nsXULContentSink.cpp
dom/xul/nsXULElement.cpp
xpcom/build/Services.py
xpcom/components/ManifestParser.cpp
--- a/chrome/nsChromeRegistry.cpp
+++ b/chrome/nsChromeRegistry.cpp
@@ -103,19 +103,16 @@ nsChromeRegistry::~nsChromeRegistry()
 {
   gChromeRegistry = nullptr;
 }
 
 NS_INTERFACE_MAP_BEGIN(nsChromeRegistry)
   NS_INTERFACE_MAP_ENTRY(nsIChromeRegistry)
   NS_INTERFACE_MAP_ENTRY(nsIXULChromeRegistry)
   NS_INTERFACE_MAP_ENTRY(nsIToolkitChromeRegistry)
-#ifdef MOZ_XUL
-  NS_INTERFACE_MAP_ENTRY(nsIXULOverlayProvider)
-#endif
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIChromeRegistry)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsChromeRegistry)
 NS_IMPL_RELEASE(nsChromeRegistry)
 
--- a/chrome/nsChromeRegistry.h
+++ b/chrome/nsChromeRegistry.h
@@ -5,20 +5,16 @@
 
 #ifndef nsChromeRegistry_h
 #define nsChromeRegistry_h
 
 #include "nsIToolkitChromeRegistry.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 
-#ifdef MOZ_XUL
-#include "nsIXULOverlayProvider.h"
-#endif
-
 #include "nsString.h"
 #include "nsURIHashKey.h"
 #include "nsInterfaceHashtable.h"
 #include "nsXULAppAPI.h"
 
 #include "mozilla/FileLocation.h"
 
 class nsPIDOMWindowOuter;
@@ -31,19 +27,16 @@ class nsIURL;
 // sense for one side erroring out in the other.
 
 // for component registration
 // {47049e42-1d87-482a-984d-56ae185e367a}
 #define NS_CHROMEREGISTRY_CID \
 { 0x47049e42, 0x1d87, 0x482a, { 0x98, 0x4d, 0x56, 0xae, 0x18, 0x5e, 0x36, 0x7a } }
 
 class nsChromeRegistry : public nsIToolkitChromeRegistry,
-#ifdef MOZ_XUL
-                         public nsIXULOverlayProvider,
-#endif
                          public nsIObserver,
                          public nsSupportsWeakReference
 {
 public:
   NS_DECL_ISUPPORTS
 
   // nsIXULChromeRegistry methods:
   NS_IMETHOD ReloadChrome() override;
@@ -123,18 +116,16 @@ public:
   };
 
   virtual void ManifestContent(ManifestProcessingContext& cx, int lineno,
                                char *const * argv, int flags) = 0;
   virtual void ManifestLocale(ManifestProcessingContext& cx, int lineno,
                               char *const * argv, int flags) = 0;
   virtual void ManifestSkin(ManifestProcessingContext& cx, int lineno,
                             char *const * argv, int flags) = 0;
-  virtual void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
-                               char *const * argv, int flags) = 0;
   virtual void ManifestOverride(ManifestProcessingContext& cx, int lineno,
                                 char *const * argv, int flags) = 0;
   virtual void ManifestResource(ManifestProcessingContext& cx, int lineno,
                                 char *const * argv, int flags) = 0;
 
   // Available flags
   enum {
     // This package should use the new XPCNativeWrappers to separate
--- a/chrome/nsChromeRegistryChrome.cpp
+++ b/chrome/nsChromeRegistryChrome.cpp
@@ -302,17 +302,16 @@ nsChromeRegistryChrome::Observe(nsISuppo
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsChromeRegistryChrome::CheckForNewChrome()
 {
   mPackagesHash.Clear();
-  mOverlayHash.Clear();
   mOverrideTable.Clear();
 
   mDynamicRegistration = false;
 
   nsComponentManagerImpl::gComponentManager->RereadChromeManifests();
 
   mDynamicRegistration = true;
 
@@ -538,64 +537,16 @@ void
 nsChromeRegistryChrome::nsProviderArray::EnumerateToArray(nsTArray<nsCString> *a)
 {
   int32_t i = mArray.Length();
   while (i--) {
     a->AppendElement(mArray[i].provider);
   }
 }
 
-void
-nsChromeRegistryChrome::OverlayListEntry::AddURI(nsIURI* aURI)
-{
-  int32_t i = mArray.Count();
-  while (i--) {
-    bool equals;
-    if (NS_SUCCEEDED(aURI->Equals(mArray[i], &equals)) && equals)
-      return;
-  }
-
-  mArray.AppendObject(aURI);
-}
-
-void
-nsChromeRegistryChrome::OverlayListHash::Add(nsIURI* aBase, nsIURI* aOverlay)
-{
-  OverlayListEntry* entry = mTable.PutEntry(aBase);
-  if (entry)
-    entry->AddURI(aOverlay);
-}
-
-const nsCOMArray<nsIURI>*
-nsChromeRegistryChrome::OverlayListHash::GetArray(nsIURI* aBase)
-{
-  OverlayListEntry* entry = mTable.GetEntry(aBase);
-  if (!entry)
-    return nullptr;
-
-  return &entry->mArray;
-}
-
-#ifdef MOZ_XUL
-NS_IMETHODIMP
-nsChromeRegistryChrome::GetXULOverlays(nsIURI *aChromeURL,
-                                       nsISimpleEnumerator **aResult)
-{
-  nsCOMPtr<nsIURI> chromeURLWithoutHash;
-  if (aChromeURL) {
-    aChromeURL->CloneIgnoringRef(getter_AddRefs(chromeURLWithoutHash));
-  }
-  const nsCOMArray<nsIURI>* parray = mOverlayHash.GetArray(chromeURLWithoutHash);
-  if (!parray)
-    return NS_NewEmptyEnumerator(aResult);
-
-  return NS_NewArrayEnumerator(aResult, *parray);
-}
-#endif // MOZ_XUL
-
 nsIURI*
 nsChromeRegistry::ManifestProcessingContext::GetManifestURI()
 {
   if (!mManifestURI) {
     nsCString uri;
     mFile.GetURIString(uri);
     NS_NewURI(getter_AddRefs(mManifestURI), uri);
   }
@@ -753,43 +704,16 @@ nsChromeRegistryChrome::ManifestSkin(Man
     ChromePackage chromePackage;
     ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
                                   mSelectedSkin);
     SendManifestEntry(chromePackage);
   }
 }
 
 void
-nsChromeRegistryChrome::ManifestOverlay(ManifestProcessingContext& cx, int lineno,
-                                        char *const * argv, int flags)
-{
-  char* base = argv[0];
-  char* overlay = argv[1];
-
-  nsCOMPtr<nsIURI> baseuri = cx.ResolveURI(base);
-  nsCOMPtr<nsIURI> overlayuri = cx.ResolveURI(overlay);
-  if (!baseuri || !overlayuri) {
-    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
-                          "During chrome registration, unable to create URI.");
-    return;
-  }
-
-  if (!CanLoadResource(overlayuri)) {
-    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
-                          "Cannot register non-local URI '%s' as an overlay.", overlay);
-    return;
-  }
-
-  nsCOMPtr<nsIURI> baseuriWithoutHash;
-  baseuri->CloneIgnoringRef(getter_AddRefs(baseuriWithoutHash));
-
-  mOverlayHash.Add(baseuriWithoutHash, overlayuri);
-}
-
-void
 nsChromeRegistryChrome::ManifestOverride(ManifestProcessingContext& cx, int lineno,
                                          char *const * argv, int flags)
 {
   char* chrome = argv[0];
   char* resolved = argv[1];
 
   nsCOMPtr<nsIURI> chromeuri = cx.ResolveURI(chrome);
   nsCOMPtr<nsIURI> resolveduri = cx.ResolveURI(resolved);
--- a/chrome/nsChromeRegistryChrome.h
+++ b/chrome/nsChromeRegistryChrome.h
@@ -36,21 +36,16 @@ class nsChromeRegistryChrome : public ns
   NS_IMETHOD IsLocaleRTL(const nsACString& package,
                          bool *aResult) override;
   NS_IMETHOD GetSelectedLocale(const nsACString& aPackage,
                                bool aAsBCP47,
                                nsACString& aLocale) override;
   NS_IMETHOD Observe(nsISupports *aSubject, const char *aTopic,
                      const char16_t *someData) override;
 
-#ifdef MOZ_XUL
-  NS_IMETHOD GetXULOverlays(nsIURI *aURI,
-                            nsISimpleEnumerator **_retval) override;
-#endif
-
   // If aChild is non-null then it is a new child to notify. If aChild is
   // null, then we have installed new chrome and we are resetting all of our
   // children's registered chrome.
   void SendRegisteredChrome(mozilla::dom::PContentParent* aChild);
 
  private:
   struct PackageEntry;
   static void ChromePackageFromPackageEntry(const nsACString& aPackageName,
@@ -109,65 +104,29 @@ class nsChromeRegistryChrome : public ns
     ~PackageEntry() { }
 
     nsCOMPtr<nsIURI> baseURI;
     uint32_t         flags;
     nsProviderArray  locales;
     nsProviderArray  skins;
   };
 
-  class OverlayListEntry : public nsURIHashKey
-  {
-   public:
-    typedef nsURIHashKey::KeyType        KeyType;
-    typedef nsURIHashKey::KeyTypePointer KeyTypePointer;
-
-    explicit OverlayListEntry(KeyTypePointer aKey) : nsURIHashKey(aKey) { }
-    OverlayListEntry(OverlayListEntry&& toMove) : nsURIHashKey(std::move(toMove)),
-                                                  mArray(std::move(toMove.mArray)) { }
-    ~OverlayListEntry() { }
-
-    void AddURI(nsIURI* aURI);
-
-    nsCOMArray<nsIURI> mArray;
-  };
-
-  class OverlayListHash
-  {
-   public:
-    OverlayListHash() { }
-    ~OverlayListHash() { }
-
-    void Add(nsIURI* aBase, nsIURI* aOverlay);
-    void Clear() { mTable.Clear(); }
-    const nsCOMArray<nsIURI>* GetArray(nsIURI* aBase);
-
-   private:
-    nsTHashtable<OverlayListEntry> mTable;
-  };
-
-  // Hashes on the file to be overlaid (chrome://browser/content/browser.xul)
-  // to a list of overlays
-  OverlayListHash mOverlayHash;
-
   bool mProfileLoaded;
   bool mDynamicRegistration;
 
   nsCString mSelectedSkin;
 
   // Hash of package names ("global") to PackageEntry objects
   nsClassHashtable<nsCStringHashKey, PackageEntry> mPackagesHash;
 
   virtual void ManifestContent(ManifestProcessingContext& cx, int lineno,
                                char *const * argv, int flags) override;
   virtual void ManifestLocale(ManifestProcessingContext& cx, int lineno,
                               char *const * argv, int flags) override;
   virtual void ManifestSkin(ManifestProcessingContext& cx, int lineno,
                             char *const * argv, int flags) override;
-  virtual void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
-                               char *const * argv, int flags) override;
   virtual void ManifestOverride(ManifestProcessingContext& cx, int lineno,
                                 char *const * argv, int flags) override;
   virtual void ManifestResource(ManifestProcessingContext& cx, int lineno,
                                 char *const * argv, int flags) override;
 };
 
 #endif // nsChromeRegistryChrome_h
--- a/chrome/nsChromeRegistryContent.cpp
+++ b/chrome/nsChromeRegistryContent.cpp
@@ -233,23 +233,16 @@ nsChromeRegistryContent::GetSelectedLoca
 
 NS_IMETHODIMP
 nsChromeRegistryContent::Observe(nsISupports* aSubject, const char* aTopic,
                                  const char16_t* aData)
 {
   CONTENT_NOT_IMPLEMENTED();
 }
 
-NS_IMETHODIMP
-nsChromeRegistryContent::GetXULOverlays(nsIURI *aChromeURL,
-                                        nsISimpleEnumerator **aResult)
-{
-  CONTENT_NOT_IMPLEMENTED();
-}
-
 void
 nsChromeRegistryContent::ManifestContent(ManifestProcessingContext& cx,
                                          int lineno, char *const * argv,
                                          int flags)
 {
   CONTENT_NOTREACHED();
 }
 
@@ -265,23 +258,16 @@ void
 nsChromeRegistryContent::ManifestSkin(ManifestProcessingContext& cx,
                                       int lineno,
                                       char *const * argv, int flags)
 {
   CONTENT_NOTREACHED();
 }
 
 void
-nsChromeRegistryContent::ManifestOverlay(ManifestProcessingContext& cx, int lineno,
-                                         char *const * argv, int flags)
-{
-  CONTENT_NOTREACHED();
-}
-
-void
 nsChromeRegistryContent::ManifestOverride(ManifestProcessingContext& cx,
                                           int lineno,
                                           char *const * argv, int flags)
 {
   CONTENT_NOTREACHED();
 }
 
 void
--- a/chrome/nsChromeRegistryContent.h
+++ b/chrome/nsChromeRegistryContent.h
@@ -30,18 +30,16 @@ class nsChromeRegistryContent : public n
   NS_IMETHOD CheckForOSAccessibility() override;
   NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic,
                      const char16_t* aData) override;
   NS_IMETHOD IsLocaleRTL(const nsACString& package,
                          bool *aResult) override;
   NS_IMETHOD GetSelectedLocale(const nsACString& aPackage,
                                bool aAsBCP47,
                                nsACString& aLocale) override;
-  NS_IMETHOD GetXULOverlays(nsIURI *aChromeURL,
-                            nsISimpleEnumerator **aResult) override;
 
   void RegisterPackage(const ChromePackage& aPackage);
   void RegisterOverride(const OverrideMapping& aOverride);
   void RegisterSubstitution(const SubstitutionMapping& aResource);
 
  private:
   struct PackageEntry
   {
@@ -63,17 +61,15 @@ class nsChromeRegistryContent : public n
   nsCString mLocale;
 
   virtual void ManifestContent(ManifestProcessingContext& cx, int lineno,
                                char *const * argv, int flags) override;
   virtual void ManifestLocale(ManifestProcessingContext& cx, int lineno,
                               char *const * argv, int flags) override;
   virtual void ManifestSkin(ManifestProcessingContext& cx, int lineno,
                             char *const * argv, int flags) override;
-  virtual void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
-                               char *const * argv, int flags) override;
   virtual void ManifestOverride(ManifestProcessingContext& cx, int lineno,
                                 char *const * argv, int flags) override;
   virtual void ManifestResource(ManifestProcessingContext& cx, int lineno,
                                 char *const * argv, int flags) override;
 };
 
 #endif // nsChromeRegistryContent_h
--- a/dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/gecko_dom.js
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/gecko_dom.js
@@ -502,17 +502,16 @@ Document.prototype.getElementsByTagNameN
  * @param {Node} externalNode
  * @param {boolean} deep
  * @return {Node}
  */
 Document.prototype.importNode = function(externalNode, deep) {};
 
 /** @param {string} uri */
 Document.prototype.load = function(uri) {};
-Document.prototype.loadOverlay;
 
 /**
  * @see https://developer.mozilla.org/en/DOM/document.open
  */
 Document.prototype.open;
 
 /**
  * @see https://developer.mozilla.org/en/Midas
--- a/dom/webidl/XULDocument.webidl
+++ b/dom/webidl/XULDocument.webidl
@@ -43,29 +43,9 @@ interface XULDocument : Document {
   void removeBroadcastListenerFor(Element broadcaster, Element observer,
                                   DOMString attr);
 
   [Throws]
   void persist([TreatNullAs=EmptyString] DOMString id, DOMString attr);
 
   [Throws]
   BoxObject? getBoxObjectFor(Element? element);
-
-  /**
-   * Loads a XUL overlay and merges it with the current document, notifying an
-   * observer when the merge is complete.
-   * @param   url
-   *          The URL of the overlay to load and merge
-   * @param   observer
-   *          An object implementing nsIObserver that will be notified with a
-   *          message of topic "xul-overlay-merged" when the merge is complete.
-   *          The subject parameter of |observe| will QI to a nsIURI - the URI
-   *          of the merged overlay. This parameter is optional and may be null.
-   *
-   * NOTICE:  In the 2.0 timeframe this API will change such that the
-   *          implementation will fire a DOMXULOverlayMerged event upon merge
-   *          completion rather than notifying an observer. Do not rely on this
-   *          API's behavior _not_ to change because it will!
-   *          - Ben Goodger (8/23/2005)
-   */
-  [Throws]
-  void loadOverlay(DOMString url, MozObserver? observer);
 };
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -33,17 +33,16 @@
 #include "nsIContentViewer.h"
 #include "nsIStreamListener.h"
 #include "nsITimer.h"
 #include "nsDocShell.h"
 #include "nsGkAtoms.h"
 #include "nsXMLContentSink.h"
 #include "nsXULContentSink.h"
 #include "nsXULContentUtils.h"
-#include "nsIXULOverlayProvider.h"
 #include "nsIStringEnumerator.h"
 #include "nsDocElementCreatedNotificationRunner.h"
 #include "nsNetUtil.h"
 #include "nsParserCIID.h"
 #include "nsPIBoxObject.h"
 #include "mozilla/dom/BoxObject.h"
 #include "nsString.h"
 #include "nsPIDOMWindow.h"
@@ -101,26 +100,16 @@ using namespace mozilla::dom;
 
 //----------------------------------------------------------------------
 //
 // CIDs
 //
 
 static NS_DEFINE_CID(kParserCID,                 NS_PARSER_CID);
 
-static bool IsOverlayAllowed(nsIURI* aURI)
-{
-    bool canOverlay = false;
-    if (NS_SUCCEEDED(aURI->SchemeIs("about", &canOverlay)) && canOverlay)
-        return true;
-    if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &canOverlay)) && canOverlay)
-        return true;
-    return false;
-}
-
 //----------------------------------------------------------------------
 //
 // Miscellaneous Constants
 //
 
 const nsForwardReference::Phase nsForwardReference::kPasses[] = {
     nsForwardReference::eConstruction,
     nsForwardReference::eHookup,
@@ -159,20 +148,18 @@ namespace dom {
 
 XULDocument::XULDocument(void)
     : XMLDocument("application/vnd.mozilla.xul+xml"),
       mNextSrcLoadWaiter(nullptr),
       mApplyingPersistedAttrs(false),
       mIsWritingFastLoad(false),
       mDocumentLoaded(false),
       mStillWalking(false),
-      mRestrictPersistence(false),
       mPendingSheets(0),
       mDocLWTheme(Doc_Theme_Uninitialized),
-      mState(eState_Master),
       mCurrentScriptProto(nullptr),
       mOffThreadCompiling(false),
       mOffThreadCompileStringBuf(nullptr),
       mOffThreadCompileStringLength(0),
       mResolutionPhase(nsForwardReference::eStart),
       mBroadcasterMap(nullptr),
       mInitialLayoutComplete(false),
       mHandlingDelayedAttrChange(false),
@@ -192,19 +179,16 @@ XULDocument::XULDocument(void)
 XULDocument::~XULDocument()
 {
     NS_ASSERTION(mNextSrcLoadWaiter == nullptr,
         "unreferenced document still waiting for script source to load?");
 
     // In case we failed somewhere early on and the forward observer
     // decls never got resolved.
     mForwardReferences.Clear();
-    // Likewise for any references we have to IDs where we might
-    // look for persisted data:
-    mPersistenceIds.Clear();
 
     // Destroy our broadcaster map.
     delete mBroadcasterMap;
 
     Preferences::UnregisterCallback(XULDocument::DirectionChanged,
                                     "intl.uidirection", this);
 
     if (mOffThreadCompileStringBuf) {
@@ -246,37 +230,20 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(XULDocume
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(XULDocument, XMLDocument)
     NS_ASSERTION(!nsCCUncollectableMarker::InGeneration(cb, tmp->GetMarkedCCGeneration()),
                  "Shouldn't traverse XULDocument!");
     // XXX tmp->mForwardReferences?
     // XXX tmp->mContextStack?
 
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCurrentPrototype)
-    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMasterPrototype)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCommandDispatcher)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrototypes)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocalStore)
 
-    if (tmp->mOverlayLoadObservers) {
-        for (auto iter = tmp->mOverlayLoadObservers->Iter();
-             !iter.Done();
-             iter.Next()) {
-            NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mOverlayLoadObservers value");
-            cb.NoteXPCOMChild(iter.Data());
-        }
-    }
-    if (tmp->mPendingOverlayLoadNotifications) {
-        for (auto iter = tmp->mPendingOverlayLoadNotifications->Iter();
-             !iter.Done();
-             iter.Next()) {
-            NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mPendingOverlayLoadNotifications value");
-            cb.NoteXPCOMChild(iter.Data());
-        }
-    }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(XULDocument, XMLDocument)
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mCommandDispatcher)
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocalStore)
     //XXX We should probably unlink all the objects we traverse.
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
@@ -388,17 +355,17 @@ XULDocument::StartDocumentLoad(const cha
         // load has finished loading before trying to add cloned style sheets.
         // XULDocument::EndLoad will call proto->NotifyLoadDone, which will
         // find all racing documents and notify them via OnPrototypeLoadDone,
         // which will add style sheet clones to each document.
         bool loaded;
         rv = proto->AwaitLoadDone(this, &loaded);
         if (NS_FAILED(rv)) return rv;
 
-        mMasterPrototype = mCurrentPrototype = proto;
+        mCurrentPrototype = proto;
 
         // Set up the right principal on ourselves.
         SetPrincipal(proto->DocumentPrincipal());
 
         // We need a listener, even if proto is not yet loaded, in which
         // event the listener's OnStopRequest method does nothing, and all
         // the interesting work happens below XULDocument::EndLoad, from
         // the call there to mCurrentPrototype->NotifyLoadDone().
@@ -438,46 +405,33 @@ XULDocument::StartDocumentLoad(const cha
             nsXULPrototypeCache::GetInstance()->PutPrototype(mCurrentPrototype);
         }
     }
 
     NS_IF_ADDREF(*aDocListener);
     return NS_OK;
 }
 
-// This gets invoked after a prototype for this document or one of
-// its overlays is fully built in the content sink.
+// This gets invoked after the prototype for this document is fully built in the
+// content sink.
 void
 XULDocument::EndLoad()
 {
-    // This can happen if an overlay fails to load
-    if (!mCurrentPrototype)
-        return;
-
     nsresult rv;
 
     // Whack the prototype document into the cache so that the next
     // time somebody asks for it, they don't need to load it by hand.
 
     nsCOMPtr<nsIURI> uri = mCurrentPrototype->GetURI();
     bool isChrome = IsChromeURI(uri);
 
     // Remember if the XUL cache is on
     bool useXULCache = nsXULPrototypeCache::GetInstance()->IsEnabled();
 
-    // If the current prototype is an overlay document (non-master prototype)
-    // and we're filling the FastLoad disk cache, tell the cache we're done
-    // loading it, and write the prototype. The master prototype is put into
-    // the cache earlier in XULDocument::StartDocumentLoad.
-    if (useXULCache && mIsWritingFastLoad && isChrome &&
-        mMasterPrototype != mCurrentPrototype) {
-        nsXULPrototypeCache::GetInstance()->WritePrototype(mCurrentPrototype);
-    }
-
-    if (IsOverlayAllowed(uri) && isChrome && useXULCache) {
+    if (isChrome && useXULCache) {
         // If it's a chrome prototype document, then notify any
         // documents that raced to load the prototype, and awaited
         // its load completion via proto->AwaitLoadDone().
         rv = mCurrentPrototype->NotifyLoadDone();
         if (NS_FAILED(rv)) return;
     }
 
     OnPrototypeLoadDone(true);
@@ -501,37 +455,16 @@ XULDocument::OnPrototypeLoadDone(bool aR
     if (NS_FAILED(rv)) return rv;
 
     if (aResumeWalk) {
         rv = ResumeWalk();
     }
     return rv;
 }
 
-// called when an error occurs parsing a document
-bool
-XULDocument::OnDocumentParserError()
-{
-  // don't report errors that are from overlays
-  if (mCurrentPrototype && mMasterPrototype != mCurrentPrototype) {
-    nsCOMPtr<nsIURI> uri = mCurrentPrototype->GetURI();
-    if (IsChromeURI(uri)) {
-      nsCOMPtr<nsIObserverService> os =
-        mozilla::services::GetObserverService();
-      if (os)
-        os->NotifyObservers(uri, "xul-overlay-parsererror",
-                            EmptyString().get());
-    }
-
-    return false;
-  }
-
-  return true;
-}
-
 static void
 ClearBroadcasterMapEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry)
 {
     BroadcasterMapEntry* entry =
         static_cast<BroadcasterMapEntry*>(aEntry);
     for (size_t i = entry->mListeners.Length() - 1; i != (size_t)-1; --i) {
         delete entry->mListeners[i];
     }
@@ -997,23 +930,16 @@ XULDocument::ResolveForwardReferences()
                         // fixup because we removed from list
                         --i;
                         break;
 
                     case nsForwardReference::eResolve_Later:
                         // do nothing. we'll try again later
                         ;
                     }
-
-                    if (mResolutionPhase == nsForwardReference::eStart) {
-                        // Resolve() loaded a dynamic overlay,
-                        // (see XULDocument::LoadOverlayInternal()).
-                        // Return for now, we will be called again.
-                        return NS_OK;
-                    }
                 }
             }
         }
 
         ++pass;
     }
 
     mForwardReferences.Clear();
@@ -1589,25 +1515,20 @@ XULDocument::PrepareToLoadPrototype(nsIU
     if (NS_FAILED(rv)) return rv;
 
     rv = mCurrentPrototype->InitPrincipal(aURI, aDocumentPrincipal);
     if (NS_FAILED(rv)) {
         mCurrentPrototype = nullptr;
         return rv;
     }
 
-    // Bootstrap the master document prototype.
-    if (! mMasterPrototype) {
-        mMasterPrototype = mCurrentPrototype;
-        // Set our principal based on the master proto.
-        SetPrincipal(aDocumentPrincipal);
-    }
+    SetPrincipal(aDocumentPrincipal);
 
     // Create a XUL content sink, a parser, and kick off a load for
-    // the overlay.
+    // the document.
     RefPtr<XULContentSinkImpl> sink = new XULContentSinkImpl();
 
     rv = sink->Init(this, mCurrentPrototype);
     NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to initialize datasource sink");
     if (NS_FAILED(rv)) return rv;
 
     nsCOMPtr<nsIParser> parser = do_CreateInstance(kParserCID, &rv);
     NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create parser");
@@ -1640,21 +1561,16 @@ XULDocument::ApplyPersistentAttributes()
             return NS_ERROR_NOT_INITIALIZED;
         }
     }
 
     mApplyingPersistedAttrs = true;
     ApplyPersistentAttributesInternal();
     mApplyingPersistedAttrs = false;
 
-    // After we've applied persistence once, we should only reapply
-    // it to nodes created by overlays
-    mRestrictPersistence = true;
-    mPersistenceIds.Clear();
-
     return NS_OK;
 }
 
 
 nsresult
 XULDocument::ApplyPersistentAttributesInternal()
 {
     nsCOMArray<Element> elements;
@@ -1678,20 +1594,16 @@ XULDocument::ApplyPersistentAttributesIn
         ids->HasMore(&hasmore);
         if (!hasmore) {
             break;
         }
 
         nsAutoString id;
         ids->GetNext(id);
 
-        if (mRestrictPersistence && !mPersistenceIds.Contains(id)) {
-            continue;
-        }
-
         nsIdentifierMapEntry* entry = mIdentifierMap.GetEntry(id);
         if (!entry) {
             continue;
         }
 
         // We want to hold strong refs to the elements while applying
         // persistent attributes, just in case.
         elements.Clear();
@@ -1893,61 +1805,48 @@ XULDocument::PrepareToWalk()
             MOZ_LOG(gXULLog, LogLevel::Error,
                    ("xul: error parsing '%s'", urlspec.get()));
         }
 
         return NS_OK;
     }
 
     nsINode* nodeToInsertBefore = nsINode::GetFirstChild();
-    if (mState != eState_Master) {
-        nodeToInsertBefore = GetRootElement();
-    }
 
     const nsTArray<RefPtr<nsXULPrototypePI> >& processingInstructions =
         mCurrentPrototype->GetProcessingInstructions();
 
     uint32_t total = processingInstructions.Length();
     for (uint32_t i = 0; i < total; ++i) {
         rv = CreateAndInsertPI(processingInstructions[i],
                                this, nodeToInsertBefore);
         if (NS_FAILED(rv)) return rv;
     }
 
-    // Now check the chrome registry for any additional overlays.
-    rv = AddChromeOverlays();
-    if (NS_FAILED(rv)) return rv;
-
-    // Do one-time initialization if we're preparing to walk the
-    // master document's prototype.
+    // Do one-time initialization.
     RefPtr<Element> root;
 
-    if (mState == eState_Master) {
-        // Add the root element
-        rv = CreateElementFromPrototype(proto, getter_AddRefs(root), true);
-        if (NS_FAILED(rv)) return rv;
-
-        rv = AppendChildTo(root, false);
-        if (NS_FAILED(rv)) return rv;
-
-        // Block onload until we've finished building the complete
-        // document content model.
-        BlockOnload();
-
-        nsContentUtils::AddScriptRunner(
-            new nsDocElementCreatedNotificationRunner(this));
-    }
+    // Add the root element
+    rv = CreateElementFromPrototype(proto, getter_AddRefs(root), true);
+    if (NS_FAILED(rv)) return rv;
+
+    rv = AppendChildTo(root, false);
+    if (NS_FAILED(rv)) return rv;
+
+    // Block onload until we've finished building the complete
+    // document content model.
+    BlockOnload();
+
+    nsContentUtils::AddScriptRunner(
+        new nsDocElementCreatedNotificationRunner(this));
 
     // There'd better not be anything on the context stack at this
     // point! This is the basis case for our "induction" in
     // ResumeWalk(), below, which'll assume that there's always a
-    // content element on the context stack if either 1) we're in the
-    // "master" document, or 2) we're in an overlay, and we've got
-    // more than one prototype element (the single, root "overlay"
-    // element) on the stack.
+    // content element on the context stack if we're in the document.
     NS_ASSERTION(mContextStack.Depth() == 0, "something's on the context stack already");
     if (mContextStack.Depth() != 0)
         return NS_ERROR_UNEXPECTED;
 
     rv = mContextStack.Push(proto, root);
     if (NS_FAILED(rv)) return rv;
 
     return NS_OK;
@@ -1962,18 +1861,16 @@ XULDocument::CreateAndInsertPI(const nsX
 
     RefPtr<ProcessingInstruction> node =
         NS_NewXMLProcessingInstruction(mNodeInfoManager, aProtoPI->mTarget,
                                        aProtoPI->mData);
 
     nsresult rv;
     if (aProtoPI->mTarget.EqualsLiteral("xml-stylesheet")) {
         rv = InsertXMLStylesheetPI(aProtoPI, aParent, aBeforeThis, node);
-    } else if (aProtoPI->mTarget.EqualsLiteral("xul-overlay")) {
-        rv = InsertXULOverlayPI(aProtoPI, aParent, aBeforeThis, node);
     } else {
         // No special processing, just add the PI to the document.
         rv = aParent->InsertChildBefore(node->AsContent(),
                                         aBeforeThis
                                           ? aBeforeThis->AsContent() : nullptr,
                                         false);
     }
 
@@ -2023,349 +1920,29 @@ XULDocument::InsertXMLStylesheetPI(const
     if (update.ShouldBlock()) {
         ++mPendingSheets;
     }
 
     return NS_OK;
 }
 
 nsresult
-XULDocument::InsertXULOverlayPI(const nsXULPrototypePI* aProtoPI,
-                                nsINode* aParent,
-                                nsINode* aBeforeThis,
-                                nsIContent* aPINode)
-{
-    nsresult rv;
-
-    rv = aParent->InsertChildBefore(aPINode->AsContent(),
-                                    aBeforeThis
-                                      ? aBeforeThis->AsContent() : nullptr,
-                                    false);
-    if (NS_FAILED(rv)) return rv;
-
-    // xul-overlay PI is special only in prolog
-    if (!nsContentUtils::InProlog(aPINode)) {
-        return NS_OK;
-    }
-
-    nsAutoString href;
-    nsContentUtils::GetPseudoAttributeValue(aProtoPI->mData,
-                                            nsGkAtoms::href,
-                                            href);
-
-    // If there was no href, we can't do anything with this PI
-    if (href.IsEmpty()) {
-        return NS_OK;
-    }
-
-    // Add the overlay to our list of overlays that need to be processed.
-    nsCOMPtr<nsIURI> uri;
-
-    rv = NS_NewURI(getter_AddRefs(uri), href, nullptr,
-                   mCurrentPrototype->GetURI());
-    if (NS_SUCCEEDED(rv)) {
-        // We insert overlays into mUnloadedOverlays at the same index in
-        // document order, so they end up in the reverse of the document
-        // order in mUnloadedOverlays.
-        // This is needed because the code in ResumeWalk loads the overlays
-        // by processing the last item of mUnloadedOverlays and removing it
-        // from the array.
-        mUnloadedOverlays.InsertElementAt(0, uri);
-        rv = NS_OK;
-    } else if (rv == NS_ERROR_MALFORMED_URI) {
-        // The URL is bad, move along. Don't propagate for now.
-        // XXX report this to the Error Console (bug 359846)
-        rv = NS_OK;
-    }
-
-    return rv;
-}
-
-nsresult
-XULDocument::AddChromeOverlays()
-{
-    nsresult rv;
-
-    nsCOMPtr<nsIURI> docUri = mCurrentPrototype->GetURI();
-
-    /* overlays only apply to chrome or about URIs */
-    if (!IsOverlayAllowed(docUri)) return NS_OK;
-
-    nsCOMPtr<nsIXULOverlayProvider> chromeReg =
-        mozilla::services::GetXULOverlayProviderService();
-    // In embedding situations, the chrome registry may not provide overlays,
-    // or even exist at all; that's OK.
-    NS_ENSURE_TRUE(chromeReg, NS_OK);
-
-    nsCOMPtr<nsISimpleEnumerator> overlays;
-    rv = chromeReg->GetXULOverlays(docUri, getter_AddRefs(overlays));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    bool moreOverlays;
-    nsCOMPtr<nsISupports> next;
-    nsCOMPtr<nsIURI> uri;
-
-    while (NS_SUCCEEDED(rv = overlays->HasMoreElements(&moreOverlays)) &&
-           moreOverlays) {
-
-        rv = overlays->GetNext(getter_AddRefs(next));
-        if (NS_FAILED(rv) || !next) break;
-
-        uri = do_QueryInterface(next);
-        if (!uri) {
-            NS_ERROR("Chrome registry handed me a non-nsIURI object!");
-            continue;
-        }
-
-        // Same comment as in XULDocument::InsertXULOverlayPI
-        mUnloadedOverlays.InsertElementAt(0, uri);
-    }
-
-    return rv;
-}
-
-void
-XULDocument::LoadOverlay(const nsAString& aURL, nsIObserver* aObserver,
-                         ErrorResult& aRv)
-{
-    nsresult rv;
-
-    nsCOMPtr<nsIURI> uri;
-    rv = NS_NewURI(getter_AddRefs(uri), aURL, nullptr);
-    if (NS_FAILED(rv)) {
-        aRv.Throw(rv);
-        return;
-    }
-
-    if (aObserver) {
-        nsIObserver* obs = nullptr;
-        if (!mOverlayLoadObservers) {
-          mOverlayLoadObservers = new nsInterfaceHashtable<nsURIHashKey,nsIObserver>;
-        }
-        obs = mOverlayLoadObservers->GetWeak(uri);
-
-        if (obs) {
-            // We don't support loading the same overlay twice into the same
-            // document - that doesn't make sense anyway.
-            aRv.Throw(NS_ERROR_FAILURE);
-            return;
-        }
-        mOverlayLoadObservers->Put(uri, aObserver);
-    }
-    bool shouldReturn, failureFromContent;
-    rv = LoadOverlayInternal(uri, true, &shouldReturn, &failureFromContent);
-    if (NS_FAILED(rv)) {
-        // remove the observer if LoadOverlayInternal generated an error
-        if (mOverlayLoadObservers) {
-            mOverlayLoadObservers->Remove(uri);
-        }
-        aRv.Throw(rv);
-        return;
-    }
-}
-
-nsresult
-XULDocument::LoadOverlayInternal(nsIURI* aURI, bool aIsDynamic,
-                                 bool* aShouldReturn,
-                                 bool* aFailureFromContent)
-{
-    nsresult rv;
-
-    // XUL overlays are in the process of being removed. In a Firefox build,
-    // loading an overlay will no longer work and display an error in the
-    // console. In automation, doing so will cause a crash.
-    // However, overlays are allowed in other applications (e.g. Thunderbird)
-    // while they work on removing them. See bug 1448162.
-#ifdef MOZ_BREAK_XUL_OVERLAYS
-    nsCString docSpec;
-    mCurrentPrototype->GetURI()->GetSpec(docSpec);
-    nsCString overlaySpec;
-    aURI->GetSpec(overlaySpec);
-    nsPrintfCString msg("Attempt to load overlay %s into %s\n",
-                        overlaySpec.get(),
-                        docSpec.get());
-    nsCOMPtr<nsIConsoleService> consoleSvc =
-        do_GetService("@mozilla.org/consoleservice;1");
-    if (consoleSvc) {
-        consoleSvc->LogStringMessage(NS_ConvertASCIItoUTF16(msg).get());
-    }
-    printf("%s", msg.get());
-    if (xpc::IsInAutomation()) {
-        MOZ_CRASH("Attempt to load overlay.");
-    }
-    return NS_ERROR_NOT_AVAILABLE;
-#endif
-
-    *aShouldReturn = false;
-    *aFailureFromContent = false;
-
-    if (MOZ_LOG_TEST(gXULLog, LogLevel::Debug)) {
-        nsCOMPtr<nsIURI> uri;
-        mChannel->GetOriginalURI(getter_AddRefs(uri));
-
-        MOZ_LOG(gXULLog, LogLevel::Debug,
-                ("xul: %s loading overlay %s",
-                 uri ? uri->GetSpecOrDefault().get() : "",
-                 aURI->GetSpecOrDefault().get()));
-    }
-
-    if (aIsDynamic)
-        mResolutionPhase = nsForwardReference::eStart;
-
-    // Look in the prototype cache for the prototype document with
-    // the specified overlay URI. Only use the cache if the containing
-    // document is chrome otherwise it may not have a system principal and
-    // the cached document will, see bug 565610.
-    bool overlayIsChrome = IsChromeURI(aURI);
-    bool documentIsChrome = mDocumentURI ?
-        IsChromeURI(mDocumentURI) : false;
-    mCurrentPrototype = overlayIsChrome && documentIsChrome ?
-        nsXULPrototypeCache::GetInstance()->GetPrototype(aURI) : nullptr;
-
-    // Same comment as nsChromeProtocolHandler::NewChannel and
-    // XULDocument::StartDocumentLoad
-    // - Ben Goodger
-    //
-    // We don't abort on failure here because there are too many valid
-    // cases that can return failure, and the null-ness of |proto| is
-    // enough to trigger the fail-safe parse-from-disk solution.
-    // Example failure cases (for reference) include:
-    //
-    // NS_ERROR_NOT_AVAILABLE: the URI was not found in the FastLoad file,
-    //                         parse from disk
-    // other: the FastLoad file, XUL.mfl, could not be found, probably
-    //        due to being accessed before a profile has been selected
-    //        (e.g. loading chrome for the profile manager itself).
-    //        The .xul file must be parsed from disk.
-
-    bool useXULCache = nsXULPrototypeCache::GetInstance()->IsEnabled();
-    if (useXULCache && mCurrentPrototype) {
-        bool loaded;
-        rv = mCurrentPrototype->AwaitLoadDone(this, &loaded);
-        if (NS_FAILED(rv)) return rv;
-
-        if (! loaded) {
-            // Return to the main event loop and eagerly await the
-            // prototype overlay load's completion. When the content
-            // sink completes, it will trigger an EndLoad(), which'll
-            // wind us back up here, in ResumeWalk().
-            *aShouldReturn = true;
-            return NS_OK;
-        }
-
-        MOZ_LOG(gXULLog, LogLevel::Debug, ("xul: overlay was cached"));
-
-        // Found the overlay's prototype in the cache, fully loaded. If
-        // this is a dynamic overlay, this will call ResumeWalk.
-        // Otherwise, we'll return to ResumeWalk, which called us.
-        return OnPrototypeLoadDone(aIsDynamic);
-    }
-    else {
-        // Not there. Initiate a load.
-        MOZ_LOG(gXULLog, LogLevel::Debug, ("xul: overlay was not cached"));
-
-        if (mIsGoingAway) {
-            MOZ_LOG(gXULLog, LogLevel::Debug, ("xul: ...and document already destroyed"));
-            return NS_ERROR_NOT_AVAILABLE;
-        }
-
-        // We'll set the right principal on the proto doc when we get
-        // OnStartRequest from the parser, so just pass in a null principal for
-        // now.
-        nsCOMPtr<nsIParser> parser;
-        rv = PrepareToLoadPrototype(aURI, "view", nullptr, getter_AddRefs(parser));
-        if (NS_FAILED(rv)) return rv;
-
-        // Predicate mIsWritingFastLoad on the XUL cache being enabled,
-        // so we don't have to re-check whether the cache is enabled all
-        // the time.
-        mIsWritingFastLoad = useXULCache;
-
-        nsCOMPtr<nsIStreamListener> listener = do_QueryInterface(parser);
-        if (! listener)
-            return NS_ERROR_UNEXPECTED;
-
-        // Add an observer to the parser; this'll get called when
-        // Necko fires its On[Start|Stop]Request() notifications,
-        // and will let us recover from a missing overlay.
-        RefPtr<ParserObserver> parserObserver =
-            new ParserObserver(this, mCurrentPrototype);
-        parser->Parse(aURI, parserObserver);
-        parserObserver = nullptr;
-
-        nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
-        nsCOMPtr<nsIChannel> channel;
-        // Set the owner of the channel to be our principal so
-        // that the overlay's JSObjects etc end up being created
-        // with the right principal and in the correct
-        // compartment.
-        rv = NS_NewChannel(getter_AddRefs(channel),
-                           aURI,
-                           NodePrincipal(),
-                           nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS |
-                           nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
-                           nsIContentPolicy::TYPE_OTHER,
-                           nullptr, // PerformanceStorage
-                           group);
-
-        if (NS_SUCCEEDED(rv)) {
-            rv = channel->AsyncOpen2(listener);
-        }
-
-        if (NS_FAILED(rv)) {
-            // Abandon this prototype
-            mCurrentPrototype = nullptr;
-
-            // The parser won't get an OnStartRequest and
-            // OnStopRequest, so it needs a Terminate.
-            parser->Terminate();
-
-            // Just move on to the next overlay.
-            ReportMissingOverlay(aURI);
-
-            // XXX the error could indicate an internal error as well...
-            *aFailureFromContent = true;
-            return rv;
-        }
-
-        // If it's a 'chrome:' prototype document, then put it into
-        // the prototype cache; other XUL documents will be reloaded
-        // each time.  We must do this after AsyncOpen,
-        // or chrome code will wrongly create a cached chrome channel
-        // instead of a real one. Prototypes are only cached when the
-        // document to be overlayed is chrome to avoid caching overlay
-        // scripts with incorrect principals, see bug 565610.
-        if (useXULCache && overlayIsChrome && documentIsChrome) {
-            nsXULPrototypeCache::GetInstance()->PutPrototype(mCurrentPrototype);
-        }
-
-        // Return to the main event loop and eagerly await the
-        // overlay load's completion. When the content sink
-        // completes, it will trigger an EndLoad(), which'll wind
-        // us back in ResumeWalk().
-        if (!aIsDynamic)
-            *aShouldReturn = true;
-    }
-    return NS_OK;
-}
-
-nsresult
 XULDocument::ResumeWalk()
 {
     // Walk the prototype and build the delegate content model. The
     // walk is performed in a top-down, left-to-right fashion. That
     // is, a parent is built before any of its children; a node is
     // only built after all of its siblings to the left are fully
     // constructed.
     //
     // It is interruptable so that transcluded documents (e.g.,
     // <html:script src="..." />) can be properly re-loaded if the
     // cached copy of the document becomes stale.
     nsresult rv;
-    nsCOMPtr<nsIURI> overlayURI =
+    nsCOMPtr<nsIURI> docURI =
         mCurrentPrototype ? mCurrentPrototype->GetURI() : nullptr;
 
     while (1) {
         // Begin (or resume) walking the current prototype.
 
         while (mContextStack.Depth() > 0) {
             // Look at the top of the stack to determine what we're
             // currently working on.
@@ -2377,115 +1954,76 @@ XULDocument::ResumeWalk()
                           // inclusive) have already been constructed
             rv = mContextStack.Peek(&proto, getter_AddRefs(element), &indx);
             if (NS_FAILED(rv)) return rv;
 
             if (indx >= (int32_t)proto->mChildren.Length()) {
                 if (element) {
                     // We've processed all of the prototype's children. If
                     // we're in the master prototype, do post-order
-                    // document-level hookup. (An overlay will get its
-                    // document hookup done when it's successfully
-                    // resolved.)
-                    if (mState == eState_Master) {
-                        AddElementToDocumentPost(element->AsElement());
-
-                        if (element->NodeInfo()->Equals(nsGkAtoms::style,
-                                                        kNameSpaceID_XHTML) ||
-                            element->NodeInfo()->Equals(nsGkAtoms::style,
-                                                        kNameSpaceID_SVG)) {
-                            // XXX sucks that we have to do this -
-                            // see bug 370111
-                            nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
-                                do_QueryInterface(element);
-                            NS_ASSERTION(ssle, "<html:style> doesn't implement "
-                                               "nsIStyleSheetLinkingElement?");
-                            Unused << ssle->UpdateStyleSheet(nullptr);
-                        }
+                    // document-level hookup.
+                    AddElementToDocumentPost(element->AsElement());
+
+                    if (element->NodeInfo()->Equals(nsGkAtoms::style,
+                                                    kNameSpaceID_XHTML) ||
+                        element->NodeInfo()->Equals(nsGkAtoms::style,
+                                                    kNameSpaceID_SVG)) {
+                        // XXX sucks that we have to do this -
+                        // see bug 370111
+                        nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
+                            do_QueryInterface(element);
+                        NS_ASSERTION(ssle, "<html:style> doesn't implement "
+                                           "nsIStyleSheetLinkingElement?");
+                        Unused << ssle->UpdateStyleSheet(nullptr);
                     }
                 }
                 // Now pop the context stack back up to the parent
                 // element and continue the prototype walk.
                 mContextStack.Pop();
                 continue;
             }
 
             // Grab the next child, and advance the current context stack
             // to the next sibling to our right.
             nsXULPrototypeNode* childproto = proto->mChildren[indx];
             mContextStack.SetTopIndex(++indx);
 
-            // Whether we're in the "first ply" of an overlay:
-            // the "hookup" nodes. In the case !processingOverlayHookupNodes,
-            // we're in the master document -or- we're in an overlay, and far
-            // enough down into the overlay's content that we can simply build
-            // the delegates and attach them to the parent node.
-            bool processingOverlayHookupNodes = (mState == eState_Overlay) &&
-                                                  (mContextStack.Depth() == 1);
-
-            NS_ASSERTION(element || processingOverlayHookupNodes,
-                         "no element on context stack");
+            NS_ASSERTION(element, "no element on context stack");
 
             switch (childproto->mType) {
             case nsXULPrototypeNode::eType_Element: {
                 // An 'element', which may contain more content.
                 nsXULPrototypeElement* protoele =
                     static_cast<nsXULPrototypeElement*>(childproto);
 
                 RefPtr<Element> child;
 
-                if (!processingOverlayHookupNodes) {
-                    rv = CreateElementFromPrototype(protoele,
-                                                    getter_AddRefs(child),
-                                                    false);
-                    if (NS_FAILED(rv)) return rv;
-
-                    // ...and append it to the content model.
-                    rv = element->AppendChildTo(child, false);
-                    if (NS_FAILED(rv)) return rv;
-
-                    // If we're only restoring persisted things on
-                    // some elements, store the ID here to do that.
-                    if (mRestrictPersistence) {
-                        nsAtom* id = child->GetID();
-                        if (id) {
-                            mPersistenceIds.PutEntry(nsDependentAtomString(id));
-                        }
-                    }
-
-                    // do pre-order document-level hookup, but only if
-                    // we're in the master document. For an overlay,
-                    // this will happen when the overlay is
-                    // successfully resolved.
-                    if (mState == eState_Master)
-                        AddElementToDocumentPre(child);
-                }
-                else {
-                    // We're in the "first ply" of an overlay: the
-                    // "hookup" nodes. Create an 'overlay' element so
-                    // that we can continue to build content, and
-                    // enter a forward reference so we can hook it up
-                    // later.
-                    rv = CreateOverlayElement(protoele, getter_AddRefs(child));
-                    if (NS_FAILED(rv)) return rv;
-                }
+
+                rv = CreateElementFromPrototype(protoele,
+                                                getter_AddRefs(child),
+                                                false);
+                if (NS_FAILED(rv)) return rv;
+
+                // ...and append it to the content model.
+                rv = element->AppendChildTo(child, false);
+                if (NS_FAILED(rv)) return rv;
+
+                // do pre-order document-level hookup.
+                AddElementToDocumentPre(child);
 
                 // If it has children, push the element onto the context
                 // stack and begin to process them.
                 if (protoele->mChildren.Length() > 0) {
                     rv = mContextStack.Push(protoele, child);
                     if (NS_FAILED(rv)) return rv;
                 }
                 else {
-                    if (mState == eState_Master) {
-                        // If there are no children, and we're in the
-                        // master document, do post-order document hookup
-                        // immediately.
-                        AddElementToDocumentPost(child);
-                    }
+                    // If there are no children, do post-order document hookup
+                    // immediately.
+                    AddElementToDocumentPost(child);
                 }
             }
             break;
 
             case nsXULPrototypeNode::eType_Script: {
                 // A script reference. Execute the script immediately;
                 // this may have side effects in the content model.
                 nsXULPrototypeScript* scriptproto =
@@ -2508,57 +2046,49 @@ XULDocument::ResumeWalk()
                     rv = ExecuteScript(scriptproto);
                     if (NS_FAILED(rv)) return rv;
                 }
             }
             break;
 
             case nsXULPrototypeNode::eType_Text: {
                 // A simple text node.
-
-                if (!processingOverlayHookupNodes) {
-                    // This does mean that text nodes that are direct children
-                    // of <overlay> get ignored.
-
-                    RefPtr<nsTextNode> text =
-                        new nsTextNode(mNodeInfoManager);
-
-                    nsXULPrototypeText* textproto =
-                        static_cast<nsXULPrototypeText*>(childproto);
-                    text->SetText(textproto->mValue, false);
-
-                    rv = element->AppendChildTo(text, false);
-                    NS_ENSURE_SUCCESS(rv, rv);
-                }
+                RefPtr<nsTextNode> text =
+                    new nsTextNode(mNodeInfoManager);
+
+                nsXULPrototypeText* textproto =
+                    static_cast<nsXULPrototypeText*>(childproto);
+                text->SetText(textproto->mValue, false);
+
+                rv = element->AppendChildTo(text, false);
+                NS_ENSURE_SUCCESS(rv, rv);
             }
             break;
 
             case nsXULPrototypeNode::eType_PI: {
                 nsXULPrototypePI* piProto =
                     static_cast<nsXULPrototypePI*>(childproto);
 
-                // <?xul-overlay?> and <?xml-stylesheet?> don't have effect
-                // outside the prolog, like they used to. Issue a warning.
-
-                if (piProto->mTarget.EqualsLiteral("xml-stylesheet") ||
-                    piProto->mTarget.EqualsLiteral("xul-overlay")) {
+                // <?xml-stylesheet?> doesn't have an effect
+                // outside the prolog, like it used to. Issue a warning.
+
+                if (piProto->mTarget.EqualsLiteral("xml-stylesheet")) {
 
                     const char16_t* params[] = { piProto->mTarget.get() };
 
                     nsContentUtils::ReportToConsole(
                                         nsIScriptError::warningFlag,
                                         NS_LITERAL_CSTRING("XUL Document"), nullptr,
                                         nsContentUtils::eXUL_PROPERTIES,
                                         "PINotInProlog",
                                         params, ArrayLength(params),
-                                        overlayURI);
+                                        docURI);
                 }
 
-                nsIContent* parent = processingOverlayHookupNodes ?
-                    GetRootElement() : element.get();
+                nsIContent* parent = element.get();
 
                 if (parent) {
                     // an inline script could have removed the root element
                     rv = CreateAndInsertPI(piProto, parent, nullptr);
                     NS_ENSURE_SUCCESS(rv, rv);
                 }
             }
             break;
@@ -2566,53 +2096,17 @@ XULDocument::ResumeWalk()
             default:
                 MOZ_ASSERT_UNREACHABLE("Unexpected nsXULPrototypeNode::Type");
             }
         }
 
         // Once we get here, the context stack will have been
         // depleted. That means that the entire prototype has been
         // walked and content has been constructed.
-
-        // If we're not already, mark us as now processing overlays.
-        mState = eState_Overlay;
-
-        // If there are no overlay URIs, then we're done.
-        uint32_t count = mUnloadedOverlays.Length();
-        if (! count)
-            break;
-
-        nsCOMPtr<nsIURI> uri = mUnloadedOverlays[count-1];
-        mUnloadedOverlays.RemoveElementAt(count - 1);
-
-        bool shouldReturn, failureFromContent;
-        rv = LoadOverlayInternal(uri, false, &shouldReturn,
-                                 &failureFromContent);
-        if (failureFromContent)
-            // The failure |rv| was the result of a problem in the content
-            // rather than an unexpected problem in our implementation, so
-            // just continue with the next overlay.
-            continue;
-        if (NS_FAILED(rv))
-            return rv;
-        if (mOverlayLoadObservers) {
-            nsIObserver *obs = mOverlayLoadObservers->GetWeak(overlayURI);
-            if (obs) {
-                // This overlay has an unloaded overlay, so it will never
-                // notify. The best we can do is to notify for the unloaded
-                // overlay instead, assuming nobody is already notifiable
-                // for it. Note that this will confuse the observer.
-                if (!mOverlayLoadObservers->GetWeak(uri))
-                    mOverlayLoadObservers->Put(uri, obs);
-                mOverlayLoadObservers->Remove(overlayURI);
-            }
-        }
-        if (shouldReturn)
-            return NS_OK;
-        overlayURI.swap(uri);
+        break;
     }
 
     // If we get here, there is nothing left for us to walk. The content
     // model is built and ready for layout.
     rv = ResolveForwardReferences();
     if (NS_FAILED(rv)) return rv;
 
     ApplyPersistentAttributes();
@@ -2658,17 +2152,17 @@ XULDocument::DoneWalking()
         if (nsCOMPtr<nsIXULWindow> win = GetXULWindowIfToplevelChrome()) {
             // We're the chrome document!
             win->BeforeStartLayout();
         }
 
         StartLayout();
 
         if (mIsWritingFastLoad && IsChromeURI(mDocumentURI))
-            nsXULPrototypeCache::GetInstance()->WritePrototype(mMasterPrototype);
+            nsXULPrototypeCache::GetInstance()->WritePrototype(mCurrentPrototype);
 
         NS_ASSERTION(mDelayFrameLoaderInitialization,
                      "mDelayFrameLoaderInitialization should be true!");
         mDelayFrameLoaderInitialization = false;
         NS_WARNING_ASSERTION(
           mUpdateNestLevel == 0,
           "Constructing XUL document in middle of an update?");
         if (mUpdateNestLevel == 0) {
@@ -2677,79 +2171,16 @@ XULDocument::DoneWalking()
 
         NS_DOCUMENT_NOTIFY_OBSERVERS(EndLoad, (this));
 
         // DispatchContentLoadedEvents undoes the onload-blocking we
         // did in PrepareToWalk().
         DispatchContentLoadedEvents();
 
         mInitialLayoutComplete = true;
-
-        // Walk the set of pending load notifications and notify any observers.
-        // See below for detail.
-        if (mPendingOverlayLoadNotifications) {
-            nsInterfaceHashtable<nsURIHashKey,nsIObserver>* observers =
-                mOverlayLoadObservers.get();
-            for (auto iter = mPendingOverlayLoadNotifications->Iter();
-                 !iter.Done();
-                 iter.Next()) {
-                nsIURI* aKey = iter.Key();
-                iter.Data()->Observe(aKey, "xul-overlay-merged",
-                                     EmptyString().get());
-
-                if (observers) {
-                  observers->Remove(aKey);
-                }
-
-                iter.Remove();
-            }
-        }
-    }
-    else {
-        if (mOverlayLoadObservers) {
-            nsCOMPtr<nsIURI> overlayURI = mCurrentPrototype->GetURI();
-            nsCOMPtr<nsIObserver> obs;
-            if (mInitialLayoutComplete) {
-                // We have completed initial layout, so just send the notification.
-                mOverlayLoadObservers->Get(overlayURI, getter_AddRefs(obs));
-                if (obs)
-                    obs->Observe(overlayURI, "xul-overlay-merged", EmptyString().get());
-                mOverlayLoadObservers->Remove(overlayURI);
-            }
-            else {
-                // If we have not yet displayed the document for the first time
-                // (i.e. we came in here as the result of a dynamic overlay load
-                // which was spawned by a binding-attached event caused by
-                // StartLayout() on the master prototype - we must remember that
-                // this overlay has been merged and tell the listeners after
-                // StartLayout() is completely finished rather than doing so
-                // immediately - otherwise we may be executing code that needs to
-                // access XBL Binding implementations on nodes for which frames
-                // have not yet been constructed because their bindings have not
-                // yet been attached. This can be a race condition because dynamic
-                // overlay loading can take varying amounts of time depending on
-                // whether or not the overlay prototype is in the XUL cache. The
-                // most likely effect of this bug is odd UI initialization due to
-                // methods and properties that do not work.
-                // XXXbz really, we shouldn't be firing binding constructors
-                // until after StartLayout returns!
-
-                if (!mPendingOverlayLoadNotifications) {
-                    mPendingOverlayLoadNotifications =
-                        new nsInterfaceHashtable<nsURIHashKey,nsIObserver>;
-                }
-
-                mPendingOverlayLoadNotifications->Get(overlayURI, getter_AddRefs(obs));
-                if (!obs) {
-                    mOverlayLoadObservers->Get(overlayURI, getter_AddRefs(obs));
-                    NS_ASSERTION(obs, "null overlay load observer?");
-                    mPendingOverlayLoadNotifications->Put(overlayURI, obs);
-                }
-            }
-        }
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 XULDocument::StyleSheetLoaded(StyleSheet* aSheet,
                               bool aWasDeferred,
@@ -2828,30 +2259,16 @@ XULDocument::MaybeBroadcast()
 
 void
 XULDocument::EndUpdate()
 {
     XMLDocument::EndUpdate();
     MaybeBroadcast();
 }
 
-void
-XULDocument::ReportMissingOverlay(nsIURI* aURI)
-{
-    MOZ_ASSERT(aURI, "Must have a URI");
-
-    NS_ConvertUTF8toUTF16 utfSpec(aURI->GetSpecOrDefault());
-    const char16_t* params[] = { utfSpec.get() };
-    nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
-                                    NS_LITERAL_CSTRING("XUL Document"), this,
-                                    nsContentUtils::eXUL_PROPERTIES,
-                                    "MissingOverlay",
-                                    params, ArrayLength(params));
-}
-
 nsresult
 XULDocument::LoadScript(nsXULPrototypeScript* aScriptProto, bool* aBlock)
 {
     // Load a transcluded script
     nsresult rv;
 
     bool isChromeDoc = IsChromeURI(mDocumentURI);
 
@@ -3077,31 +2494,16 @@ XULDocument::OnScriptCompileComplete(JSS
         // the true crime story.)
         bool useXULCache = nsXULPrototypeCache::GetInstance()->IsEnabled();
 
         if (useXULCache && IsChromeURI(mDocumentURI) && scriptProto->HasScriptObject()) {
             JS::Rooted<JSScript*> script(RootingCx(), scriptProto->GetScriptObject());
             nsXULPrototypeCache::GetInstance()->PutScript(
                                scriptProto->mSrcURI, script);
         }
-
-        if (mIsWritingFastLoad && mCurrentPrototype != mMasterPrototype) {
-            // If we are loading an overlay script, try to serialize
-            // it to the FastLoad file here.  Master scripts will be
-            // serialized when the master prototype document gets
-            // written, at the bottom of ResumeWalk.  That way, master
-            // out-of-line scripts are serialized in the same order that
-            // they'll be read, in the FastLoad file, which reduces the
-            // number of seeks that dump the underlying stream's buffer.
-            //
-            // Ignore the return value, as we don't need to propagate
-            // a failure to write to the FastLoad file, because this
-            // method aborts that whole process on error.
-            scriptProto->SerializeOutOfLine(nullptr, mCurrentPrototype);
-        }
         // ignore any evaluation errors
     }
 
     rv = ResumeWalk();
 
     // Load a pointer to the prototype-script's list of XULDocuments who
     // raced to load the same script
     XULDocument** docp = &scriptProto->mSrcLoadWaiters;
@@ -3226,37 +2628,16 @@ XULDocument::CreateElementFromPrototype(
     }
 
     result.forget(aResult);
 
     return NS_OK;
 }
 
 nsresult
-XULDocument::CreateOverlayElement(nsXULPrototypeElement* aPrototype,
-                                  Element** aResult)
-{
-    nsresult rv;
-
-    RefPtr<Element> element;
-    rv = CreateElementFromPrototype(aPrototype, getter_AddRefs(element), false);
-    if (NS_FAILED(rv)) return rv;
-
-    OverlayForwardReference* fwdref =
-        new OverlayForwardReference(this, element);
-
-    // transferring ownership to ya...
-    rv = AddForwardReference(fwdref);
-    if (NS_FAILED(rv)) return rv;
-
-    element.forget(aResult);
-    return NS_OK;
-}
-
-nsresult
 XULDocument::AddAttributes(nsXULPrototypeElement* aPrototype,
                            Element* aElement)
 {
     nsresult rv;
 
     for (uint32_t i = 0; i < aPrototype->mNumAttributes; ++i) {
         nsXULPrototypeAttribute* protoattr = &(aPrototype->mAttributes[i]);
         nsAutoString  valueStr;
@@ -3271,261 +2652,16 @@ XULDocument::AddAttributes(nsXULPrototyp
     }
 
     return NS_OK;
 }
 
 
 //----------------------------------------------------------------------
 //
-// XULDocument::OverlayForwardReference
-//
-
-nsForwardReference::Result
-XULDocument::OverlayForwardReference::Resolve()
-{
-    // Resolve a forward reference from an overlay element; attempt to
-    // hook it up into the main document.
-    nsresult rv;
-    RefPtr<Element> target;
-
-    nsIPresShell *shell = mDocument->GetShell();
-    bool notify = shell && shell->DidInitialize();
-
-    nsAutoString id;
-    mOverlay->GetAttr(kNameSpaceID_None, nsGkAtoms::id, id);
-    if (id.IsEmpty()) {
-        // mOverlay is a direct child of <overlay> and has no id.
-        // Insert it under the root element in the base document.
-        Element* root = mDocument->GetRootElement();
-        if (!root) {
-            return eResolve_Error;
-        }
-
-        rv = XULDocument::InsertElement(root, mOverlay, notify);
-        if (NS_FAILED(rv)) return eResolve_Error;
-
-        target = mOverlay;
-    }
-    else {
-        // The hook-up element has an id, try to match it with an element
-        // with the same id in the base document.
-        target = mDocument->GetElementById(id);
-
-        // If we can't find the element in the document, defer the hookup
-        // until later.
-        if (!target)
-            return eResolve_Later;
-
-        rv = Merge(target, mOverlay, notify);
-        if (NS_FAILED(rv)) return eResolve_Error;
-    }
-
-    // Check if 'target' is still in our document --- it might not be!
-    if (!notify && target->GetUncomposedDoc() == mDocument) {
-        // Add child and any descendants to the element map
-        // XXX this is bogus, the content in 'target' might already be
-        // in the document
-        rv = mDocument->AddSubtreeToDocument(target);
-        if (NS_FAILED(rv)) return eResolve_Error;
-    }
-
-    if (MOZ_LOG_TEST(gXULLog, LogLevel::Debug)) {
-        nsAutoCString idC;
-        LossyCopyUTF16toASCII(id, idC);
-        MOZ_LOG(gXULLog, LogLevel::Debug,
-               ("xul: overlay resolved '%s'",
-                idC.get()));
-    }
-
-    mResolved = true;
-    return eResolve_Succeeded;
-}
-
-
-
-nsresult
-XULDocument::OverlayForwardReference::Merge(Element* aTargetElement,
-                                            Element* aOverlayElement,
-                                            bool aNotify)
-{
-    // This function is given:
-    // aTargetElement:  the element in the document whose 'id' attribute
-    //                  matches a toplevel node in our overlay.
-    // aOverlayElement: the element in the overlay document that matches
-    //                  an element in the actual document.
-    // aNotify:         whether or not content manipulation methods should
-    //                  use the aNotify parameter. After the initial
-    //                  reflow (i.e. in the dynamic overlay merge case),
-    //                  we want all the content manipulation methods we
-    //                  call to notify so that frames are constructed
-    //                  etc. Otherwise do not, since that's during initial
-    //                  document construction before StartLayout has been
-    //                  called which will do everything for us.
-    //
-    // This function merges the tree from the overlay into the tree in
-    // the document, overwriting attributes and appending child content
-    // nodes appropriately. (See XUL overlay reference for details)
-
-    nsresult rv;
-
-    // Merge attributes from the overlay content node to that of the
-    // actual document.
-    uint32_t i;
-    const nsAttrName* name;
-    for (i = 0; (name = aOverlayElement->GetAttrNameAt(i)); ++i) {
-        // We don't want to swap IDs, they should be the same.
-        if (name->Equals(nsGkAtoms::id))
-            continue;
-
-        // In certain cases merging command or observes is unsafe, so don't.
-        if (!aNotify) {
-            if (aTargetElement->NodeInfo()->Equals(nsGkAtoms::observes,
-                                                   kNameSpaceID_XUL))
-                continue;
-
-            if (name->Equals(nsGkAtoms::observes) &&
-                aTargetElement->HasAttr(kNameSpaceID_None, nsGkAtoms::observes))
-                continue;
-
-            if (name->Equals(nsGkAtoms::command) &&
-                aTargetElement->HasAttr(kNameSpaceID_None, nsGkAtoms::command) &&
-                !aTargetElement->NodeInfo()->Equals(nsGkAtoms::key,
-                                                    kNameSpaceID_XUL) &&
-                !aTargetElement->NodeInfo()->Equals(nsGkAtoms::menuitem,
-                                                   kNameSpaceID_XUL))
-                continue;
-        }
-
-        int32_t nameSpaceID = name->NamespaceID();
-        nsAtom* attr = name->LocalName();
-        nsAtom* prefix = name->GetPrefix();
-
-        nsAutoString value;
-        aOverlayElement->GetAttr(nameSpaceID, attr, value);
-
-        // Element in the overlay has the 'removeelement' attribute set
-        // so remove it from the actual document.
-        if (attr == nsGkAtoms::removeelement && value.EqualsLiteral("true")) {
-            nsCOMPtr<nsINode> parent = aTargetElement->GetParentNode();
-            if (!parent) return NS_ERROR_FAILURE;
-            parent->RemoveChildNode(aTargetElement, true);
-            return NS_OK;
-        }
-
-        rv = aTargetElement->SetAttr(nameSpaceID, attr, prefix, value, aNotify);
-        if (!NS_FAILED(rv) && !aNotify) {
-            rv = mDocument->BroadcastAttributeChangeFromOverlay(
-                    aTargetElement, nameSpaceID, attr, prefix, value);
-        }
-        if (NS_FAILED(rv)) return rv;
-    }
-
-
-    // Walk our child nodes, looking for elements that have the 'id'
-    // attribute set. If we find any, we must do a parent check in the
-    // actual document to ensure that the structure matches that of
-    // the actual document. If it does, we can call ourselves and attempt
-    // to merge inside that subtree. If not, we just append the tree to
-    // the parent like any other.
-
-    uint32_t childCount = aOverlayElement->GetChildCount();
-
-    // This must be a strong reference since it will be the only
-    // reference to a content object during part of this loop.
-    nsCOMPtr<nsIContent> currContent;
-
-    for (i = 0; i < childCount; ++i) {
-        currContent = aOverlayElement->GetFirstChild();
-
-        nsAtom *idAtom = currContent->GetID();
-
-        Element* elementInDocument = nullptr;
-        if (idAtom) {
-            nsDependentAtomString id(idAtom);
-
-            if (!id.IsEmpty()) {
-                nsIDocument *doc = aTargetElement->GetUncomposedDoc();
-                //XXXsmaug should we use ShadowRoot::GetElementById()
-                //         if doc is null?
-                if (!doc) return NS_ERROR_FAILURE;
-
-                elementInDocument = doc->GetElementById(id);
-            }
-        }
-
-        // The item has an 'id' attribute set, and we need to check with
-        // the actual document to see if an item with this id exists at
-        // this locale. If so, we want to merge the subtree under that
-        // node. Otherwise, we just do an append as if the element had
-        // no id attribute.
-        if (elementInDocument) {
-            // Given two parents, aTargetElement and aOverlayElement, we want
-            // to call merge on currContent if we find an associated
-            // node in the document with the same id as currContent that
-            // also has aTargetNode as its parent.
-
-            nsIContent* elementParent = elementInDocument->GetParent();
-
-            nsAtom *parentID = elementParent->GetID();
-            if (parentID && aTargetElement->GetID() == parentID) {
-                // The element matches. "Go Deep!"
-                //
-                // Note that currContent is necessarily an element, because
-                // elementInDocument can only be non-null when currContent has a
-                // non-null ID.
-                rv = Merge(elementInDocument, currContent->AsElement(), aNotify);
-                if (NS_FAILED(rv)) return rv;
-                nsIContent* firstChild = aOverlayElement->GetFirstChild();
-                if (firstChild) {
-                  aOverlayElement->RemoveChildNode(firstChild, false);
-                }
-
-                continue;
-            }
-        }
-
-        nsIContent* firstChild = aOverlayElement->GetFirstChild();
-        if (firstChild) {
-          aOverlayElement->RemoveChildNode(firstChild, false);
-        }
-
-        rv = InsertElement(aTargetElement, currContent, aNotify);
-        if (NS_FAILED(rv)) return rv;
-    }
-
-    return NS_OK;
-}
-
-
-
-XULDocument::OverlayForwardReference::~OverlayForwardReference()
-{
-    if (MOZ_LOG_TEST(gXULLog, LogLevel::Warning) && !mResolved) {
-        nsAutoString id;
-        mOverlay->GetAttr(kNameSpaceID_None, nsGkAtoms::id, id);
-
-        nsAutoCString idC;
-        LossyCopyUTF16toASCII(id, idC);
-
-        nsIURI *protoURI = mDocument->mCurrentPrototype->GetURI();
-
-        nsCOMPtr<nsIURI> docURI;
-        mDocument->mChannel->GetOriginalURI(getter_AddRefs(docURI));
-
-        MOZ_LOG(gXULLog, LogLevel::Warning,
-               ("xul: %s overlay failed to resolve '%s' in %s",
-                protoURI->GetSpecOrDefault().get(), idC.get(),
-                docURI ? docURI->GetSpecOrDefault().get() : ""));
-    }
-}
-
-
-//----------------------------------------------------------------------
-//
 // XULDocument::BroadcasterHookup
 //
 
 nsForwardReference::Result
 XULDocument::BroadcasterHookup::Resolve()
 {
     nsresult rv;
 
@@ -3563,54 +2699,16 @@ XULDocument::BroadcasterHookup::~Broadca
                 attributeC.get(),
                 broadcasteridC.get()));
     }
 }
 
 //----------------------------------------------------------------------
 
 nsresult
-XULDocument::BroadcastAttributeChangeFromOverlay(nsIContent* aNode,
-                                                 int32_t aNameSpaceID,
-                                                 nsAtom* aAttribute,
-                                                 nsAtom* aPrefix,
-                                                 const nsAString& aValue)
-{
-    nsresult rv = NS_OK;
-
-    if (!mBroadcasterMap || !CanBroadcast(aNameSpaceID, aAttribute))
-        return rv;
-
-    if (!aNode->IsElement())
-        return rv;
-
-    auto entry = static_cast<BroadcasterMapEntry*>
-                            (mBroadcasterMap->Search(aNode->AsElement()));
-    if (!entry)
-        return rv;
-
-    // We've got listeners: push the value.
-    for (size_t i = entry->mListeners.Length() - 1; i != (size_t)-1; --i) {
-        BroadcastListener* bl = entry->mListeners[i];
-
-        if ((bl->mAttribute != aAttribute) &&
-            (bl->mAttribute != nsGkAtoms::_asterisk))
-            continue;
-
-        nsCOMPtr<Element> l = do_QueryReferent(bl->mListener);
-        if (l) {
-            rv = l->SetAttr(aNameSpaceID, aAttribute,
-                            aPrefix, aValue, false);
-            if (NS_FAILED(rv)) return rv;
-        }
-    }
-    return rv;
-}
-
-nsresult
 XULDocument::FindBroadcaster(Element* aElement,
                              Element** aListener,
                              nsString& aBroadcasterID,
                              nsString& aAttribute,
                              Element** aBroadcaster)
 {
     mozilla::dom::NodeInfo *ni = aElement->NodeInfo();
     *aListener = nullptr;
@@ -3623,23 +2721,16 @@ XULDocument::FindBroadcaster(Element* aE
         // broadcaster element, and an 'attribute' element, which
         // specifies the name of the attribute to observe.
         nsIContent* parent = aElement->GetParent();
         if (!parent) {
              // <observes> is the root element
             return NS_FINDBROADCASTER_NOT_FOUND;
         }
 
-        // If we're still parented by an 'overlay' tag, then we haven't
-        // made it into the real document yet. Defer hookup.
-        if (parent->NodeInfo()->Equals(nsGkAtoms::overlay,
-                                       kNameSpaceID_XUL)) {
-            return NS_FINDBROADCASTER_AWAIT_OVERLAYS;
-        }
-
         *aListener = Element::FromNode(parent);
         NS_IF_ADDREF(*aListener);
 
         aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::element, aBroadcasterID);
         if (aBroadcasterID.IsEmpty()) {
             return NS_FINDBROADCASTER_NOT_FOUND;
         }
         aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::attribute, aAttribute);
@@ -3678,18 +2769,17 @@ XULDocument::FindBroadcaster(Element* aE
 
     // Make sure we got a valid listener.
     NS_ENSURE_TRUE(*aListener, NS_ERROR_UNEXPECTED);
 
     // Try to find the broadcaster element in the document.
     *aBroadcaster = GetElementById(aBroadcasterID);
 
     // If we can't find the broadcaster, then we'll need to defer the
-    // hookup. We may need to resolve some of the other overlays
-    // first.
+    // hookup. We may need to resolve some more content first.
     if (! *aBroadcaster) {
         return NS_FINDBROADCASTER_AWAIT_OVERLAYS;
     }
 
     NS_ADDREF(*aBroadcaster);
 
     return NS_FINDBROADCASTER_FOUND;
 }
@@ -3752,105 +2842,16 @@ XULDocument::CheckBroadcasterHookup(Elem
                 broadcasteridC.get()));
     }
 
     *aNeedsHookup = false;
     *aDidResolve = true;
     return NS_OK;
 }
 
-nsresult
-XULDocument::InsertElement(nsINode* aParent, nsIContent* aChild, bool aNotify)
-{
-    // Insert aChild appropriately into aParent, accounting for a
-    // 'pos' attribute set on aChild.
-
-    nsAutoString posStr;
-    bool wasInserted = false;
-
-    // insert after an element of a given id
-    if (Element* element = Element::FromNode(aChild)) {
-        element->GetAttr(kNameSpaceID_None, nsGkAtoms::insertafter, posStr);
-    }
-
-    bool isInsertAfter = true;
-    if (posStr.IsEmpty()) {
-        if (Element* element = Element::FromNode(aChild)) {
-            element->GetAttr(kNameSpaceID_None, nsGkAtoms::insertbefore, posStr);
-        }
-        isInsertAfter = false;
-    }
-
-    if (!posStr.IsEmpty()) {
-        nsIDocument *document = aParent->OwnerDoc();
-
-        nsIContent *content = nullptr;
-
-        char* str = ToNewCString(posStr);
-        char* rest;
-        char* token = nsCRT::strtok(str, ", ", &rest);
-
-        while (token) {
-            content = document->GetElementById(NS_ConvertASCIItoUTF16(token));
-            if (content)
-                break;
-
-            token = nsCRT::strtok(rest, ", ", &rest);
-        }
-        free(str);
-
-        if (content) {
-            if (content->GetParent() == aParent) {
-                nsIContent* nodeToInsertBefore =
-                  isInsertAfter ? content->GetNextSibling() : content;
-                nsresult rv = aParent->InsertChildBefore(aChild,
-                                                         nodeToInsertBefore,
-                                                         aNotify);
-                if (NS_FAILED(rv)) {
-                    return rv;
-                }
-
-                wasInserted = true;
-            }
-        }
-    }
-
-    if (!wasInserted) {
-        if (aChild->IsElement() &&
-            aChild->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::position, posStr) &&
-            !posStr.IsEmpty()) {
-            nsresult rv;
-            // Positions are one-indexed.
-            int32_t pos = posStr.ToInteger(&rv);
-            // Note: if the insertion index (which is |pos - 1|) would be less
-            // than 0 or greater than the number of children aParent has, then
-            // don't insert, since the position is bogus.  Just skip on to
-            // appending.
-            if (NS_SUCCEEDED(rv) && pos > 0 &&
-                uint32_t(pos - 1) <= aParent->GetChildCount()) {
-                nsIContent* nodeToInsertBefore =
-                    aParent->GetChildAt_Deprecated(pos - 1);
-                rv = aParent->InsertChildBefore(aChild, nodeToInsertBefore,
-                                                aNotify);
-                if (NS_SUCCEEDED(rv))
-                    wasInserted = true;
-                // If the insertion fails, then we should still
-                // attempt an append.  Thus, rather than returning rv
-                // immediately, we fall through to the final
-                // "catch-all" case that just does an AppendChildTo.
-            }
-        }
-    }
-
-    if (!wasInserted) {
-        return aParent->AppendChildTo(aChild, aNotify);
-    }
-    return NS_OK;
-}
-
 //----------------------------------------------------------------------
 //
 // CachedChromeStreamListener
 //
 
 XULDocument::CachedChromeStreamListener::CachedChromeStreamListener(XULDocument* aDocument, bool aProtoLoaded)
     : mDocument(aDocument),
       mProtoLoaded(aProtoLoaded)
@@ -3892,87 +2893,16 @@ XULDocument::CachedChromeStreamListener:
                                                          nsIInputStream* aInStr,
                                                          uint64_t aSourceOffset,
                                                          uint32_t aCount)
 {
     MOZ_ASSERT_UNREACHABLE("CachedChromeStream doesn't receive data");
     return NS_ERROR_UNEXPECTED;
 }
 
-//----------------------------------------------------------------------
-//
-// ParserObserver
-//
-
-XULDocument::ParserObserver::ParserObserver(XULDocument* aDocument,
-                                            nsXULPrototypeDocument* aPrototype)
-    : mDocument(aDocument), mPrototype(aPrototype)
-{
-}
-
-XULDocument::ParserObserver::~ParserObserver()
-{
-}
-
-NS_IMPL_ISUPPORTS(XULDocument::ParserObserver, nsIRequestObserver)
-
-NS_IMETHODIMP
-XULDocument::ParserObserver::OnStartRequest(nsIRequest *request,
-                                            nsISupports* aContext)
-{
-    // Guard against buggy channels calling OnStartRequest multiple times.
-    if (mPrototype) {
-        nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
-        nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
-        if (channel && secMan) {
-            nsCOMPtr<nsIPrincipal> principal;
-            secMan->GetChannelResultPrincipal(channel, getter_AddRefs(principal));
-
-            principal = mDocument->MaybeDowngradePrincipal(principal);
-            // Failure there is ok -- it'll just set a (safe) null principal
-            mPrototype->SetDocumentPrincipal(principal);
-        }
-
-        // Make sure to avoid cycles
-        mPrototype = nullptr;
-    }
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-XULDocument::ParserObserver::OnStopRequest(nsIRequest *request,
-                                           nsISupports* aContext,
-                                           nsresult aStatus)
-{
-    nsresult rv = NS_OK;
-
-    if (NS_FAILED(aStatus)) {
-        // If an overlay load fails, we need to nudge the prototype
-        // walk along.
-        nsCOMPtr<nsIChannel> aChannel = do_QueryInterface(request);
-        if (aChannel) {
-            nsCOMPtr<nsIURI> uri;
-            aChannel->GetOriginalURI(getter_AddRefs(uri));
-            if (uri) {
-                mDocument->ReportMissingOverlay(uri);
-            }
-        }
-
-        rv = mDocument->ResumeWalk();
-    }
-
-    // Drop the reference to the document to break cycle between the
-    // document, the parser, the content sink, and the parser
-    // observer.
-    mDocument = nullptr;
-
-    return rv;
-}
-
 already_AddRefed<nsPIWindowRoot>
 XULDocument::GetWindowRoot()
 {
   if (!mDocumentContainer) {
     return nullptr;
   }
 
     nsCOMPtr<nsPIDOMWindowOuter> piWin = mDocumentContainer->GetWindow();
--- a/dom/xul/XULDocument.h
+++ b/dom/xul/XULDocument.h
@@ -101,20 +101,16 @@ public:
      * disabled, whether the protototype was loaded, whether the
      * prototype was loaded from the cache or created by parsing the
      * actual XUL source, etc.
      *
      * @param aResumeWalk whether this should also call ResumeWalk().
      * Sometimes the caller of OnPrototypeLoadDone resumes the walk itself
      */
     nsresult OnPrototypeLoadDone(bool aResumeWalk);
-    /**
-     * Callback notifying when a document could not be parsed properly.
-     */
-    bool OnDocumentParserError();
 
     // nsINode interface overrides
     virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
                            bool aPreallocateChildren) const override;
 
     // nsICSSLoaderObserver
     NS_IMETHOD StyleSheetLoaded(mozilla::StyleSheet* aSheet,
                                 bool aWasAlternate,
@@ -169,18 +165,16 @@ public:
                                ErrorResult& aRv);
     void AddBroadcastListenerFor(Element& aBroadcaster, Element& aListener,
                                  const nsAString& aAttr, ErrorResult& aRv);
     void RemoveBroadcastListenerFor(Element& aBroadcaster, Element& aListener,
                                     const nsAString& aAttr);
     void Persist(const nsAString& aId, const nsAString& aAttr,
                  ErrorResult& aRv);
     using nsDocument::GetBoxObjectFor;
-    void LoadOverlay(const nsAString& aURL, nsIObserver* aObserver,
-                     ErrorResult& aRv);
 
 protected:
     virtual ~XULDocument();
 
     // Implementation methods
     friend nsresult
     (::NS_NewXULDocument(nsIDocument** aResult));
 
@@ -196,43 +190,32 @@ protected:
                            nsIParser** aResult);
 
     nsresult
     PrepareToLoadPrototype(nsIURI* aURI,
                            const char* aCommand,
                            nsIPrincipal* aDocumentPrincipal,
                            nsIParser** aResult);
 
-    nsresult
-    LoadOverlayInternal(nsIURI* aURI, bool aIsDynamic, bool* aShouldReturn,
-                        bool* aFailureFromContent);
-
     nsresult ApplyPersistentAttributes();
     nsresult ApplyPersistentAttributesInternal();
     nsresult ApplyPersistentAttributesToElements(const nsAString &aID,
                                                  nsCOMArray<Element>& aElements);
 
     nsresult
     AddElementToDocumentPre(Element* aElement);
 
     nsresult
     AddElementToDocumentPost(Element* aElement);
 
     nsresult
     ExecuteOnBroadcastHandlerFor(Element* aBroadcaster,
                                  Element* aListener,
                                  nsAtom* aAttr);
 
-    nsresult
-    BroadcastAttributeChangeFromOverlay(nsIContent* aNode,
-                                        int32_t aNameSpaceID,
-                                        nsAtom* aAttribute,
-                                        nsAtom* aPrefix,
-                                        const nsAString& aValue);
-
     already_AddRefed<nsPIWindowRoot> GetWindowRoot();
 
     static void DirectionChanged(const char* aPrefName, void* aData);
 
     // pseudo constants
     static int32_t gRefCnt;
 
     static LazyLogModule gXULLog;
@@ -270,22 +253,16 @@ protected:
      * Since ResumeWalk is interruptible, it's possible that last
      * stylesheet finishes loading while the PD walk is still in
      * progress (waiting for an overlay to finish loading).
      * mStillWalking prevents DoneLoading (and StartLayout) from being
      * called in this situation.
      */
     bool                       mStillWalking;
 
-    /**
-     * These two values control where persistent attributes get applied.
-     */
-    bool                           mRestrictPersistence;
-    nsTHashtable<nsStringHashKey>  mPersistenceIds;
-
     nsCOMPtr<nsIDOMXULCommandDispatcher>     mCommandDispatcher; // [OWNER] of the focus tracker
 
     uint32_t mPendingSheets;
 
     /**
      * document lightweight theme for use with :-moz-lwtheme, :-moz-lwtheme-brighttext
      * and :-moz-lwtheme-darktext
      */
@@ -318,32 +295,16 @@ protected:
         nsresult Peek(nsXULPrototypeElement** aPrototype, nsIContent** aElement, int32_t* aIndex);
 
         nsresult SetTopIndex(int32_t aIndex);
     };
 
     friend class ContextStack;
     ContextStack mContextStack;
 
-    enum State { eState_Master, eState_Overlay };
-    State mState;
-
-    /**
-     * An array of overlay nsIURIs that have yet to be resolved. The
-     * order of the array is significant: overlays at the _end_ of the
-     * array are resolved before overlays earlier in the array (i.e.,
-     * it is a stack).
-     *
-     * In the current implementation the order the overlays are loaded
-     * in is as follows: first overlays from xul-overlay PIs, in the
-     * same order as in the document, then the overlays from the chrome
-     * registry.
-     */
-    nsTArray<nsCOMPtr<nsIURI> > mUnloadedOverlays;
-
     /**
      * Load the transcluded script at the specified URI. If the
      * prototype construction must 'block' until the load has
      * completed, aBlock will be set to true.
      */
     nsresult LoadScript(nsXULPrototypeScript *aScriptProto, bool* aBlock);
 
     /**
@@ -356,23 +317,16 @@ protected:
      * Create a delegate content model element from a prototype.
      * Note that the resulting content node is not bound to any tree
      */
     nsresult CreateElementFromPrototype(nsXULPrototypeElement* aPrototype,
                                         Element** aResult,
                                         bool aIsRoot);
 
     /**
-     * Create a hook-up element to which content nodes can be attached for
-     * later resolution.
-     */
-    nsresult CreateOverlayElement(nsXULPrototypeElement* aPrototype,
-                                  Element** aResult);
-
-    /**
      * Add attributes from the prototype to the element.
      */
     nsresult AddAttributes(nsXULPrototypeElement* aPrototype, Element* aElement);
 
     /**
      * The prototype-script of the current transcluded script that is being
      * loaded.  For document.write('<script src="nestedwrite.js"><\/script>')
      * to work, these need to be in a stack element type, and we need to hold
@@ -445,40 +399,16 @@ protected:
 
         virtual Phase GetPhase() override { return eHookup; }
         virtual Result Resolve() override;
     };
 
     friend class BroadcasterHookup;
 
 
-    /**
-     * Used to hook up overlays
-     */
-    class OverlayForwardReference : public nsForwardReference
-    {
-    protected:
-        XULDocument* mDocument;      // [WEAK]
-        nsCOMPtr<Element> mOverlay; // [OWNER]
-        bool mResolved;
-
-        nsresult Merge(Element* aTargetNode, Element* aOverlayNode, bool aNotify);
-
-    public:
-        OverlayForwardReference(XULDocument* aDocument, Element* aOverlay)
-            : mDocument(aDocument), mOverlay(aOverlay), mResolved(false) {}
-
-        virtual ~OverlayForwardReference();
-
-        virtual Phase GetPhase() override { return eConstruction; }
-        virtual Result Resolve() override;
-    };
-
-    friend class OverlayForwardReference;
-
     // The out params of FindBroadcaster only have values that make sense when
     // the method returns NS_FINDBROADCASTER_FOUND.  In all other cases, the
     // values of the out params should not be relied on (though *aListener and
     // *aBroadcaster do need to be released if non-null, of course).
     nsresult
     FindBroadcaster(Element* aElement,
                     Element** aListener,
                     nsString& aBroadcasterID,
@@ -490,35 +420,23 @@ protected:
                            bool* aNeedsHookup,
                            bool* aDidResolve);
 
     void
     SynchronizeBroadcastListener(Element *aBroadcaster,
                                  Element *aListener,
                                  const nsAString &aAttr);
 
-    // FIXME: This should probably be renamed, there's nothing guaranteeing that
-    // aChild is an Element as far as I can tell!
-    static
-    nsresult
-    InsertElement(nsINode* aParent, nsIContent* aChild, bool aNotify);
-
     /**
      * The current prototype that we are walking to construct the
      * content model.
      */
     RefPtr<nsXULPrototypeDocument> mCurrentPrototype;
 
     /**
-     * The master document (outermost, .xul) prototype, from which
-     * all subdocuments get their security principals.
-     */
-    RefPtr<nsXULPrototypeDocument> mMasterPrototype;
-
-    /**
      * Owning references to all of the prototype documents that were
      * used to construct this document.
      */
     nsTArray< RefPtr<nsXULPrototypeDocument> > mPrototypes;
 
     /**
      * Prepare to walk the current prototype.
      */
@@ -543,50 +461,28 @@ protected:
      */
     nsresult
     InsertXMLStylesheetPI(const nsXULPrototypePI* aProtoPI,
                           nsINode* aParent,
                           nsINode* aBeforeThis,
                           nsIContent* aPINode);
 
     /**
-     * Inserts the passed <?xul-overlay ?> PI at the specified index.
-     * Schedules the referenced overlay URI for further processing.
-     */
-    nsresult
-    InsertXULOverlayPI(const nsXULPrototypePI* aProtoPI,
-                       nsINode* aParent,
-                       nsINode* aBeforeThis,
-                       nsIContent* aPINode);
-
-    /**
-     * Add overlays from the chrome registry to the set of unprocessed
-     * overlays still to do.
-     */
-    nsresult AddChromeOverlays();
-
-    /**
      * Resume (or initiate) an interrupted (or newly prepared)
      * prototype walk.
      */
     nsresult ResumeWalk();
 
     /**
      * Called at the end of ResumeWalk() and from StyleSheetLoaded().
      * Expects that both the prototype document walk is complete and
      * all referenced stylesheets finished loading.
      */
     nsresult DoneWalking();
 
-    /**
-     * Report that an overlay failed to load
-     * @param aURI the URI of the overlay that failed to load
-     */
-    void ReportMissingOverlay(nsIURI* aURI);
-
     class CachedChromeStreamListener : public nsIStreamListener {
     protected:
         RefPtr<XULDocument> mDocument;
         bool mProtoLoaded;
 
         virtual ~CachedChromeStreamListener();
 
     public:
@@ -595,41 +491,21 @@ protected:
 
         NS_DECL_ISUPPORTS
         NS_DECL_NSIREQUESTOBSERVER
         NS_DECL_NSISTREAMLISTENER
     };
 
     friend class CachedChromeStreamListener;
 
-
-    class ParserObserver : public nsIRequestObserver {
-    protected:
-        RefPtr<XULDocument> mDocument;
-        RefPtr<nsXULPrototypeDocument> mPrototype;
-        virtual ~ParserObserver();
-
-    public:
-        ParserObserver(XULDocument* aDocument,
-                       nsXULPrototypeDocument* aPrototype);
-
-        NS_DECL_ISUPPORTS
-        NS_DECL_NSIREQUESTOBSERVER
-    };
-
-    friend class ParserObserver;
-
     /**
      * A map from a broadcaster element to a list of listener elements.
      */
     PLDHashTable* mBroadcasterMap;
 
-    nsAutoPtr<nsInterfaceHashtable<nsURIHashKey,nsIObserver> > mOverlayLoadObservers;
-    nsAutoPtr<nsInterfaceHashtable<nsURIHashKey,nsIObserver> > mPendingOverlayLoadNotifications;
-
     bool mInitialLayoutComplete;
 
     class nsDelayedBroadcastUpdate
     {
     public:
       nsDelayedBroadcastUpdate(Element* aBroadcaster,
                                Element* aListener,
                                const nsAString &aAttr)
--- a/dom/xul/XULFrameElement.cpp
+++ b/dom/xul/XULFrameElement.cpp
@@ -74,19 +74,17 @@ XULFrameElement::GetContentDocument()
   nsCOMPtr<nsPIDOMWindowOuter> win = GetContentWindow();
   return win ? win->GetDoc() : nullptr;
 }
 
 void
 XULFrameElement::LoadSrc()
 {
   if (!IsInUncomposedDoc() ||
-      !OwnerDoc()->GetRootElement() ||
-      OwnerDoc()->GetRootElement()->
-        NodeInfo()->Equals(nsGkAtoms::overlay, kNameSpaceID_XUL)) {
+      !OwnerDoc()->GetRootElement()) {
       return;
   }
   RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
   if (!frameLoader) {
     // Check if we have an opener we need to be setting
     nsCOMPtr<nsPIDOMWindowOuter> opener = mOpener;
     if (!opener) {
       // If we are a primary xul-browser, we want to take the opener property!
--- a/dom/xul/moz.build
+++ b/dom/xul/moz.build
@@ -10,20 +10,16 @@ with Files("**"):
 if CONFIG['MOZ_BUILD_APP'] == 'browser':
     DEFINES['MOZ_BREAK_XUL_OVERLAYS'] = True
 
 MOCHITEST_MANIFESTS += ['test/mochitest.ini']
 
 MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
 
 if CONFIG['MOZ_XUL']:
-    XPIDL_SOURCES += [
-        'nsIXULOverlayProvider.idl',
-    ]
-
     EXPORTS += [
         'nsXULElement.h',
     ]
 
     EXPORTS.mozilla.dom += [
         'XULFrameElement.h',
         'XULPopupElement.h',
     ]
deleted file mode 100644
--- a/dom/xul/nsIXULOverlayProvider.idl
+++ /dev/null
@@ -1,26 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* 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/. */
-
-#include "nsISupports.idl"
-
-interface nsISimpleEnumerator;
-interface nsIURI;
-
-/**
- * The chrome registry implements this interface to give overlays
- * to the gecko XUL engine.
- */
-
-[scriptable, uuid(1d5b5b94-dc47-4050-93b7-ac092e383cad)]
-interface nsIXULOverlayProvider : nsISupports
-{
-    /**
-     * Get the XUL overlays for a particular chrome URI.
-     *
-     * @param aURI  The URI being loaded
-     * @return      An enumerator of nsIURI for the overlays of this URI 
-     */
-    nsISimpleEnumerator /*nsIURI*/ getXULOverlays(in nsIURI aURI);
-};
--- a/dom/xul/nsXULContentSink.cpp
+++ b/dom/xul/nsXULContentSink.cpp
@@ -646,23 +646,16 @@ XULContentSinkImpl::ReportError(const ch
   mTextLength = 0;
 
   // return leaving the document empty if we're asked to not add a <parsererror> root node
   nsCOMPtr<nsIDocument> idoc = do_QueryReferent(mDocument);
   if (idoc && idoc->SuppressParserErrorElement()) {
     return NS_OK;
   };
 
-  if (idoc &&
-      idoc->IsXULDocument() &&
-      !idoc->AsXULDocument()->OnDocumentParserError()) {
-    // The overlay was broken.  Don't add a messy element to the master doc.
-    return NS_OK;
-  }
-
   const char16_t* noAtts[] = { 0, 0 };
 
   NS_NAMED_LITERAL_STRING(errorNs,
                           "http://www.mozilla.org/newlayout/xml/parsererror.xml");
 
   nsAutoString parsererror(errorNs);
   parsererror.Append((char16_t)0xFFFF);
   parsererror.AppendLiteral("parsererror");
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -421,18 +421,17 @@ nsXULElement::GetEventListenerManagerFor
 {
     // XXXbz sXBL/XBL2 issue: should we instead use GetComposedDoc()
     // here, override BindToTree for those classes and munge event
     // listeners there?
     nsIDocument* doc = OwnerDoc();
 
     nsPIDOMWindowInner *window;
     Element *root = doc->GetRootElement();
-    if ((!root || root == this) && !mNodeInfo->Equals(nsGkAtoms::overlay) &&
-        (window = doc->GetInnerWindow())) {
+    if ((!root || root == this) && (window = doc->GetInnerWindow())) {
 
         nsCOMPtr<EventTarget> piTarget = do_QueryInterface(window);
 
         *aDefer = false;
         return piTarget->GetOrCreateListenerManager();
     }
 
     return nsStyledElement::GetEventListenerManagerForAttr(aAttrName, aDefer);
--- a/xpcom/build/Services.py
+++ b/xpcom/build/Services.py
@@ -9,18 +9,16 @@ def service(name, iface, contractid):
 
 
 service('ChromeRegistryService', 'nsIChromeRegistry',
         "@mozilla.org/chrome/chrome-registry;1")
 service('ToolkitChromeRegistryService', 'nsIToolkitChromeRegistry',
         "@mozilla.org/chrome/chrome-registry;1")
 service('XULChromeRegistryService', 'nsIXULChromeRegistry',
         "@mozilla.org/chrome/chrome-registry;1")
-service('XULOverlayProviderService', 'nsIXULOverlayProvider',
-        "@mozilla.org/chrome/chrome-registry;1")
 service('IOService', 'nsIIOService',
         "@mozilla.org/network/io-service;1")
 service('ObserverService', 'nsIObserverService',
         "@mozilla.org/observer-service;1")
 service('StringBundleService', 'nsIStringBundleService',
         "@mozilla.org/intl/stringbundle;1")
 service('XPConnect', 'nsIXPConnect',
         "@mozilla.org/js/xpc/XPConnect;1")
@@ -61,17 +59,16 @@ CPP_INCLUDES = """
 #include "nsNetCID.h"
 #include "nsObserverService.h"
 #include "nsXPCOMPrivate.h"
 #include "nsIIOService.h"
 #include "nsIDirectoryService.h"
 #include "nsIChromeRegistry.h"
 #include "nsIStringBundle.h"
 #include "nsIToolkitChromeRegistry.h"
-#include "nsIXULOverlayProvider.h"
 #include "IHistory.h"
 #include "nsIXPConnect.h"
 #include "nsIPermissionManager.h"
 #include "nsIServiceWorkerManager.h"
 #include "nsICacheStorageService.h"
 #include "nsIStreamTransportService.h"
 #include "nsISocketTransportService.h"
 #include "nsIURIClassifier.h"
--- a/xpcom/components/ManifestParser.cpp
+++ b/xpcom/components/ManifestParser.cpp
@@ -99,20 +99,16 @@ static const ManifestDirective kParsingT
     "locale",           3, false, true, true, true, false,
     nullptr, &nsChromeRegistry::ManifestLocale,
   },
   {
     "skin",             3, false, false, true, true, false,
     nullptr, &nsChromeRegistry::ManifestSkin,
   },
   {
-    "overlay",          2, false, true, true, false, false,
-    nullptr, &nsChromeRegistry::ManifestOverlay,
-  },
-  {
     // NB: note that while skin manifests can use this, they are only allowed
     // to use it for chrome://../skin/ URLs
     "override",         2, false, false, true, true, false,
     nullptr, &nsChromeRegistry::ManifestOverride,
   },
   {
     "resource",         2, false, true, true, false, true,
     nullptr, &nsChromeRegistry::ManifestResource,