Backed out changeset 7235d05662b0 (bug 1373984) for Android bustage. r=backout on a CLOSED TREE
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sun, 25 Jun 2017 18:30:13 +0200
changeset 366057 e29483674e5a0f3e33bd41a24417bfd28a16861b
parent 366056 eae501f2729beac5ce9010309a5a2f4097f5d6ef
child 366058 345e2a69a8baf6991bbfdc2716272f82742240ca
push id91862
push usercbook@mozilla.com
push dateMon, 26 Jun 2017 11:37:09 +0000
treeherdermozilla-inbound@74e977897768 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1373984
milestone56.0a1
backs out7235d05662b03741f84c383534a46fecc2075d58
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 7235d05662b0 (bug 1373984) for Android bustage. r=backout on a CLOSED TREE
accessible/xul/XULElementAccessibles.cpp
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/nsIDocShell.idl
dom/base/FragmentOrElement.cpp
dom/base/Location.cpp
dom/base/nsContentSink.cpp
dom/base/nsContentUtils.cpp
dom/base/nsDOMSerializer.cpp
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsFrameLoader.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsIDocument.h
dom/base/nsImageLoadingContent.cpp
dom/base/nsReferencedElement.cpp
dom/encoding/FallbackEncoding.cpp
dom/encoding/FallbackEncoding.h
dom/html/HTMLFormSubmission.cpp
dom/html/MediaDocument.cpp
dom/html/nsHTMLContentSink.cpp
dom/html/nsHTMLDocument.cpp
dom/html/nsHTMLDocument.h
dom/notification/Notification.cpp
dom/presentation/PresentationRequest.cpp
dom/script/ScriptLoadHandler.cpp
dom/script/ScriptLoader.cpp
dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
dom/webbrowserpersist/WebBrowserPersistLocalDocument.h
dom/xbl/nsXBLPrototypeBinding.cpp
dom/xbl/nsXBLResourceLoader.cpp
dom/xhr/XMLHttpRequestMainThread.cpp
dom/xhr/XMLHttpRequestMainThread.h
dom/xml/XMLDocument.cpp
dom/xml/XMLStylesheetProcessingInstruction.cpp
dom/xml/nsXMLContentSink.cpp
dom/xml/nsXMLContentSink.h
dom/xml/nsXMLFragmentContentSink.cpp
dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
dom/xslt/xslt/txMozillaTextOutput.cpp
dom/xslt/xslt/txMozillaXMLOutput.cpp
dom/xul/XULDocument.cpp
dom/xul/nsXULContentSink.cpp
dom/xul/nsXULContentSink.h
editor/libeditor/EditorBase.cpp
intl/locale/nsLanguageAtomService.cpp
intl/locale/nsLanguageAtomService.h
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/build/nsContentDLF.cpp
layout/generic/nsImageFrame.cpp
layout/style/Loader.cpp
netwerk/base/nsNetUtil.cpp
netwerk/base/nsNetUtil.h
netwerk/streamconv/converters/nsDirIndexParser.cpp
parser/html/nsHtml5DocumentBuilder.cpp
parser/html/nsHtml5DocumentBuilder.h
parser/html/nsHtml5MetaScanner.cpp
parser/html/nsHtml5MetaScannerCppSupplement.h
parser/html/nsHtml5MetaScannerHSupplement.h
parser/html/nsHtml5Parser.cpp
parser/html/nsHtml5Parser.h
parser/html/nsHtml5SpeculativeLoad.cpp
parser/html/nsHtml5StreamParser.cpp
parser/html/nsHtml5StreamParser.h
parser/html/nsHtml5TreeBuilderCppSupplement.h
parser/html/nsHtml5TreeBuilderHSupplement.h
parser/html/nsHtml5TreeOpExecutor.cpp
parser/html/nsHtml5TreeOpExecutor.h
parser/html/nsHtml5TreeOperation.cpp
parser/html/nsHtml5TreeOperation.h
parser/htmlparser/nsIContentSink.h
parser/htmlparser/nsIParser.h
parser/htmlparser/nsParser.cpp
parser/htmlparser/nsParser.h
parser/htmlparser/nsScanner.cpp
parser/htmlparser/nsScanner.h
parser/xml/nsSAXXMLReader.cpp
parser/xml/nsSAXXMLReader.h
rdf/base/nsRDFContentSink.cpp
rdf/base/nsRDFXMLParser.cpp
--- a/accessible/xul/XULElementAccessibles.cpp
+++ b/accessible/xul/XULElementAccessibles.cpp
@@ -276,13 +276,13 @@ XULLinkAccessible::AnchorURIAt(uint32_t 
   nsAutoString href;
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, href);
 
   nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
   nsIDocument* document = mContent->OwnerDoc();
 
   nsCOMPtr<nsIURI> anchorURI;
   NS_NewURI(getter_AddRefs(anchorURI), href,
-            document->GetDocumentCharacterSet(),
+            document->GetDocumentCharacterSet().get(),
             baseURI);
 
   return anchorURI.forget();
 }
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -369,25 +369,24 @@ ForEachPing(nsIContent* aContent, ForEac
   }
 
   nsCOMPtr<nsIIOService> ios = do_GetIOService();
   if (!ios) {
     return;
   }
 
   nsIDocument* doc = aContent->OwnerDoc();
-  nsAutoCString charset;
-  doc->GetDocumentCharacterSet()->Name(charset);
 
   nsWhitespaceTokenizer tokenizer(value);
 
   while (tokenizer.hasMoreTokens()) {
     nsCOMPtr<nsIURI> uri, baseURI = aContent->GetBaseURI();
     ios->NewURI(NS_ConvertUTF16toUTF8(tokenizer.nextToken()),
-                charset.get(), baseURI, getter_AddRefs(uri));
+                doc->GetDocumentCharacterSet().get(),
+                baseURI, getter_AddRefs(uri));
     // if we can't generate a valid URI, then there is nothing to do
     if (!uri) {
       continue;
     }
     // Explicitly not allow loading data: URIs
     bool isDataScheme =
       (NS_SUCCEEDED(uri->SchemeIs("data", &isDataScheme)) && isDataScheme);
 
@@ -828,18 +827,16 @@ nsDocShell::nsDocShell()
   , mBlankTiming(false)
   , mCreatingDocument(false)
 #ifdef DEBUG
   , mInEnsureScriptEnv(false)
 #endif
   , mDefaultLoadFlags(nsIRequest::LOAD_NORMAL)
   , mFrameType(FRAME_TYPE_REGULAR)
   , mPrivateBrowsingId(0)
-  , mForcedCharset(nullptr)
-  , mParentCharset(nullptr)
   , mParentCharsetSource(0)
   , mJSRunToCompletionDepth(0)
   , mTouchEventsOverride(nsIDocShell::TOUCHEVENTS_OVERRIDE_NONE)
 {
   AssertOriginAttributesMatchPrivateBrowsing();
 
   nsContentUtils::GenerateUUIDInPlace(mHistoryID);
 
@@ -2028,17 +2025,17 @@ NS_IMETHODIMP
 nsDocShell::GetCharset(nsACString& aCharset)
 {
   aCharset.Truncate();
 
   nsIPresShell* presShell = GetPresShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
   nsIDocument* doc = presShell->GetDocument();
   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
-  doc->GetDocumentCharacterSet()->Name(aCharset);
+  aCharset = doc->GetDocumentCharacterSet();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GatherCharsetMenuTelemetry()
 {
   nsCOMPtr<nsIContentViewer> viewer;
   GetContentViewer(getter_AddRefs(viewer));
@@ -2114,51 +2111,51 @@ nsDocShell::SetCharset(const nsACString&
   // set the charset override
   return SetForcedCharset(aCharset);
 }
 
 NS_IMETHODIMP
 nsDocShell::SetForcedCharset(const nsACString& aCharset)
 {
   if (aCharset.IsEmpty()) {
-    mForcedCharset = nullptr;
+    mForcedCharset.Truncate();
     return NS_OK;
   }
   const Encoding* encoding = Encoding::ForLabel(aCharset);
   if (!encoding) {
     // Reject unknown labels
     return NS_ERROR_INVALID_ARG;
   }
   if (!encoding->IsAsciiCompatible() && encoding != ISO_2022_JP_ENCODING) {
     // Reject XSS hazards
     return NS_ERROR_INVALID_ARG;
   }
-  mForcedCharset = encoding;
+  encoding->Name(mForcedCharset);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetForcedCharset(nsACString& aResult)
 {
-  mForcedCharset->Name(aResult);
+  aResult = mForcedCharset;
   return NS_OK;
 }
 
 void
-nsDocShell::SetParentCharset(const Encoding*& aCharset,
+nsDocShell::SetParentCharset(const nsACString& aCharset,
                              int32_t aCharsetSource,
                              nsIPrincipal* aPrincipal)
 {
   mParentCharset = aCharset;
   mParentCharsetSource = aCharsetSource;
   mParentCharsetPrincipal = aPrincipal;
 }
 
 void
-nsDocShell::GetParentCharset(const Encoding*& aCharset,
+nsDocShell::GetParentCharset(nsACString& aCharset,
                              int32_t* aCharsetSource,
                              nsIPrincipal** aPrincipal)
 {
   aCharset = mParentCharset;
   *aCharsetSource = mParentCharsetSource;
   NS_IF_ADDREF(*aPrincipal = mParentCharsetPrincipal);
 }
 
@@ -4190,17 +4187,17 @@ nsDocShell::AddChild(nsIDocShellTreeItem
   }
 
   if (!isWyciwyg) {
     // If this docshell is loaded from a wyciwyg: URI, don't
     // advertise our charset since it does not in any way reflect
     // the actual source charset, which is what we're trying to
     // expose here.
 
-    const Encoding* parentCS = doc->GetDocumentCharacterSet();
+    const nsACString& parentCS = doc->GetDocumentCharacterSet();
     int32_t charsetSource = doc->GetDocumentCharacterSetSource();
     // set the child's parentCharset
     childAsDocShell->SetParentCharset(parentCS,
                                       charsetSource,
                                       doc->NodePrincipal());
   }
 
   // printf("### 1 >>> Adding child. Parent CS = %s. ItemType = %d.\n",
@@ -11619,18 +11616,17 @@ nsDocShell::ScrollToAnchor(bool aCurHasR
 
     // Above will fail if the anchor name is not UTF-8.  Need to
     // convert from document charset to unicode.
     if (NS_FAILED(rv)) {
       // Get a document charset
       NS_ENSURE_TRUE(mContentViewer, NS_ERROR_FAILURE);
       nsIDocument* doc = mContentViewer->GetDocument();
       NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
-      nsAutoCString charset;
-      doc->GetDocumentCharacterSet()->Name(charset);
+      const nsACString& charset = doc->GetDocumentCharacterSet();
 
       nsCOMPtr<nsITextToSubURI> textToSubURI =
         do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
       NS_ENSURE_SUCCESS(rv, rv);
 
       // Unescape and convert to unicode
       nsAutoString uStr;
 
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -57,17 +57,16 @@
 #include "nsITabParent.h"
 #include "nsCRT.h"
 #include "prtime.h"
 #include "nsRect.h"
 #include "Units.h"
 #include "nsIDeprecationWarner.h"
 
 namespace mozilla {
-class Encoding;
 enum class TaskCategory;
 namespace dom {
 class EventTarget;
 class PendingGlobalHistoryEntry;
 typedef uint32_t ScreenOrientationInternal;
 } // namespace dom
 } // namespace mozilla
 
@@ -151,17 +150,16 @@ class nsDocShell final
   , public nsIClipboardCommands
   , public nsIDOMStorageManager
   , public nsINetworkInterceptController
   , public nsIDeprecationWarner
   , public mozilla::SupportsWeakPtr<nsDocShell>
 {
   friend class nsDSURIContentListener;
   friend class FramingChecker;
-  using Encoding = mozilla::Encoding;
 
 public:
   MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsDocShell)
 
   nsDocShell();
 
   virtual nsresult Init() override;
 
@@ -271,18 +269,16 @@ public:
   void NotifyAsyncPanZoomStopped();
 
   void SetInFrameSwap(bool aInSwap)
   {
     mInFrameSwap = aInSwap;
   }
   bool InFrameSwap();
 
-  const Encoding* GetForcedCharset() { return mForcedCharset; }
-
 private:
   bool CanSetOriginAttributes();
 
 public:
   const mozilla::OriginAttributes&
   GetOriginAttributes()
   {
     return mOriginAttributes;
@@ -1035,18 +1031,18 @@ protected:
   // On content docshells mPrivateBrowsingId == mOriginAttributes.mPrivateBrowsingId
   // On chrome docshells this value will be set, but not have the corresponding
   // origin attribute set.
   uint32_t mPrivateBrowsingId;
 
   nsString mInterceptedDocumentId;
 
 private:
-  const Encoding* mForcedCharset;
-  const Encoding* mParentCharset;
+  nsCString mForcedCharset;
+  nsCString mParentCharset;
   int32_t mParentCharsetSource;
   nsCOMPtr<nsIPrincipal> mParentCharsetPrincipal;
   nsTObserverArray<nsWeakPtr> mPrivacyObservers;
   nsTObserverArray<nsWeakPtr> mReflowObservers;
   nsTObserverArray<nsWeakPtr> mScrollObservers;
   nsCString mOriginalUriString;
   nsWeakPtr mOpener;
   mozilla::OriginAttributes mOriginAttributes;
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -6,32 +6,27 @@
 
 #include "domstubs.idl"
 #include "nsIDocShellTreeItem.idl"
 #include "nsIRequest.idl"
 
 %{ C++
 #include "js/TypeDecls.h"
 #include "mozilla/Maybe.h"
-#include "mozilla/NotNull.h"
 class nsPresContext;
 class nsIPresShell;
-namespace mozilla {
-class Encoding;
-}
 %}
 
 /**
  * The nsIDocShell interface.
  */
 
 [ptr] native nsPresContext(nsPresContext);
 [ptr] native nsIPresShell(nsIPresShell);
 [ref] native MaybeURI(mozilla::Maybe<nsCOMPtr<nsIURI>>);
-[ref] native Encoding(const mozilla::Encoding*);
 
 interface nsIURI;
 interface nsIChannel;
 interface nsIContentViewer;
 interface nsIDOMEventTarget;
 interface nsIDocShellLoadInfo;
 interface nsIEditor;
 interface nsIEditingSession;
@@ -713,21 +708,21 @@ interface nsIDocShell : nsIDocShellTreeI
    * The charset forced by the user.
    */
   attribute ACString forcedCharset;
 
   /**
    * In a child docshell, this is the charset of the parent docshell
    */
   [noscript, notxpcom, nostdcall] void setParentCharset(
-    in Encoding parentCharset,
+    in ACString parentCharset,
     in int32_t parentCharsetSource,
     in nsIPrincipal parentCharsetPrincipal);
   [noscript, notxpcom, nostdcall] void getParentCharset(
-    out Encoding parentCharset,
+    out ACString parentCharset,
     out int32_t parentCharsetSource,
     out nsIPrincipal parentCharsetPrincipal);
 
   /**
    * Whether the docShell records profile timeline markers at the moment
    */
   [infallible] attribute boolean recordProfileTimelineMarkers;
 
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -424,17 +424,17 @@ nsIContent::GetBaseURI(bool aTryUseXHRDo
   } while(elem);
 
   if (!baseAttrs.IsEmpty()) {
     doc->WarnOnceAbout(nsIDocument::eXMLBaseAttribute);
     // Now resolve against all xml:base attrs
     for (uint32_t i = baseAttrs.Length() - 1; i != uint32_t(-1); --i) {
       nsCOMPtr<nsIURI> newBase;
       nsresult rv = NS_NewURI(getter_AddRefs(newBase), baseAttrs[i],
-                              doc->GetDocumentCharacterSet(), base);
+                              doc->GetDocumentCharacterSet().get(), base);
       // Do a security check, almost the same as nsDocument::SetBaseURL()
       // Only need to do this on the final uri
       if (NS_SUCCEEDED(rv) && i == 0) {
         rv = nsContentUtils::GetSecurityManager()->
           CheckLoadURIWithPrincipal(NodePrincipal(), newBase,
                                     nsIScriptSecurityManager::STANDARD);
       }
       if (NS_SUCCEEDED(rv)) {
--- a/dom/base/Location.cpp
+++ b/dom/base/Location.cpp
@@ -34,16 +34,28 @@
 #include "NullPrincipal.h"
 #include "mozilla/Unused.h"
 #include "mozilla/dom/LocationBinding.h"
 #include "mozilla/dom/ScriptSettings.h"
 
 namespace mozilla {
 namespace dom {
 
+static nsresult
+GetDocumentCharacterSetForURI(const nsAString& aHref, nsACString& aCharset)
+{
+  aCharset.Truncate();
+
+  if (nsIDocument* doc = GetEntryDocument()) {
+    aCharset = doc->GetDocumentCharacterSet();
+  }
+
+  return NS_OK;
+}
+
 Location::Location(nsPIDOMWindowInner* aWindow, nsIDocShell *aDocShell)
   : mInnerWindow(aWindow)
 {
   MOZ_ASSERT(aDocShell);
   MOZ_ASSERT(mInnerWindow->IsInnerWindow());
 
   mDocShell = do_GetWeakReference(aDocShell);
 }
@@ -489,22 +501,21 @@ nsresult
 Location::SetHrefWithBase(const nsAString& aHref, nsIURI* aBase,
                           bool aReplace)
 {
   nsresult result;
   nsCOMPtr<nsIURI> newUri;
 
   nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell));
 
-  if (nsIDocument* doc = GetEntryDocument()) {
-    result = NS_NewURI(getter_AddRefs(newUri), aHref,
-                       doc->GetDocumentCharacterSet(), aBase);
-  } else {
+  nsAutoCString docCharset;
+  if (NS_SUCCEEDED(GetDocumentCharacterSetForURI(aHref, docCharset)))
+    result = NS_NewURI(getter_AddRefs(newUri), aHref, docCharset.get(), aBase);
+  else
     result = NS_NewURI(getter_AddRefs(newUri), aHref, nullptr, aBase);
-  }
 
   if (newUri) {
     /* Check with the scriptContext if it is currently processing a script tag.
      * If so, this must be a <script> tag with a location.href in it.
      * we want to do a replace load, in such a situation.
      * In other cases, for example if a event handler or a JS timer
      * had a location.href in it, we want to do a normal load,
      * so that the new url will be appended to Session History.
--- a/dom/base/nsContentSink.cpp
+++ b/dom/base/nsContentSink.cpp
@@ -840,19 +840,20 @@ nsContentSink::ProcessMETATag(nsIContent
 void
 nsContentSink::PrefetchHref(const nsAString &aHref,
                             nsINode *aSource,
                             bool aExplicit)
 {
   nsCOMPtr<nsIPrefetchService> prefetchService(do_GetService(NS_PREFETCHSERVICE_CONTRACTID));
   if (prefetchService) {
     // construct URI using document charset
-    auto encoding = mDocument->GetDocumentCharacterSet();
+    const nsACString &charset = mDocument->GetDocumentCharacterSet();
     nsCOMPtr<nsIURI> uri;
-    NS_NewURI(getter_AddRefs(uri), aHref, encoding,
+    NS_NewURI(getter_AddRefs(uri), aHref,
+              charset.IsEmpty() ? nullptr : PromiseFlatCString(charset).get(),
               mDocument->GetDocBaseURI());
     if (uri) {
       nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aSource);
       prefetchService->PrefetchURI(uri, mDocumentURI, domNode, aExplicit);
     }
   }
 }
 
@@ -886,19 +887,20 @@ nsContentSink::PrefetchDNS(const nsAStri
                                    mDocument->NodePrincipal()->OriginAttributesRef());
   }
 }
 
 void
 nsContentSink::Preconnect(const nsAString& aHref, const nsAString& aCrossOrigin)
 {
   // construct URI using document charset
-  auto encoding = mDocument->GetDocumentCharacterSet();
+  const nsACString& charset = mDocument->GetDocumentCharacterSet();
   nsCOMPtr<nsIURI> uri;
-  NS_NewURI(getter_AddRefs(uri), aHref, encoding,
+  NS_NewURI(getter_AddRefs(uri), aHref,
+            charset.IsEmpty() ? nullptr : PromiseFlatCString(charset).get(),
             mDocument->GetDocBaseURI());
 
   if (uri && mDocument) {
     mDocument->MaybePreconnect(uri, dom::Element::StringToCORSMode(aCrossOrigin));
   }
 }
 
 nsresult
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -3149,22 +3149,19 @@ nsContentUtils::ObjectPrincipal(JSObject
 
 // static
 nsresult
 nsContentUtils::NewURIWithDocumentCharset(nsIURI** aResult,
                                           const nsAString& aSpec,
                                           nsIDocument* aDocument,
                                           nsIURI* aBaseURI)
 {
-  if (aDocument) {
-    return NS_NewURI(aResult, aSpec,
-                     aDocument->GetDocumentCharacterSet(),
-                     aBaseURI, sIOService);
-  }
-  return NS_NewURI(aResult, aSpec, nullptr, aBaseURI, sIOService);
+  return NS_NewURI(aResult, aSpec,
+                   aDocument ? aDocument->GetDocumentCharacterSet().get() : nullptr,
+                   aBaseURI, sIOService);
 }
 
 // static
 bool
 nsContentUtils::IsCustomElementName(nsIAtom* aName)
 {
   // A valid custom element name is a sequence of characters name which
   // must match the PotentialCustomElementName production:
--- a/dom/base/nsDOMSerializer.cpp
+++ b/dom/base/nsDOMSerializer.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "nsDOMSerializer.h"
 
-#include "mozilla/Encoding.h"
 #include "nsIDocument.h"
 #include "nsIDocumentEncoder.h"
 #include "nsIDOMDocument.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentCID.h"
 #include "nsContentUtils.h"
 #include "nsError.h"
 #include "nsINode.h"
@@ -67,17 +66,17 @@ SetUpEncoder(nsIDOMNode *aRoot, const ns
 
   if (NS_FAILED(rv))
     return rv;
 
   nsAutoCString charset(aCharset);
   if (charset.IsEmpty()) {
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
     NS_ASSERTION(doc, "Need a document");
-    doc->GetDocumentCharacterSet()->Name(charset);
+    charset = doc->GetDocumentCharacterSet();
   }
   rv = encoder->SetCharset(charset);
   if (NS_FAILED(rv))
     return rv;
 
   // If we are working on the entire document we do not need to
   // specify which part to serialize
   if (!entireDocument) {
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1282,17 +1282,17 @@ static already_AddRefed<mozilla::dom::No
 nsIDocument::nsIDocument()
   : nsINode(nullNodeInfo),
     mReferrerPolicySet(false),
     mReferrerPolicy(mozilla::net::RP_Unset),
     mBlockAllMixedContent(false),
     mBlockAllMixedContentPreloads(false),
     mUpgradeInsecureRequests(false),
     mUpgradeInsecurePreloads(false),
-    mCharacterSet(WINDOWS_1252_ENCODING),
+    mCharacterSet(NS_LITERAL_CSTRING("windows-1252")),
     mCharacterSetSource(0),
     mParentDocument(nullptr),
     mCachedRootElement(nullptr),
     mNodeInfoManager(nullptr),
     mBidiEnabled(false),
     mMathMLEnabled(false),
     mIsInitialDocumentInWindow(false),
     mIgnoreDocGroupMismatches(false),
@@ -3665,32 +3665,31 @@ nsIDocument::DefaultStyleAttrURLData()
 
 void
 nsDocument::GetBaseTarget(nsAString &aBaseTarget)
 {
   aBaseTarget = mBaseTarget;
 }
 
 void
-nsDocument::SetDocumentCharacterSet(NotNull<const Encoding*> aEncoding)
-{
-  if (mCharacterSet != aEncoding) {
-    mCharacterSet = aEncoding;
-
-    nsAutoCString charsetID;
-    aEncoding->Name(charsetID);
-    NS_ConvertASCIItoUTF16 charset16(charsetID);
+nsDocument::SetDocumentCharacterSet(const nsACString& aCharSetID)
+{
+  // XXX it would be a good idea to assert the sanity of the argument,
+  // but before we figure out what to do about non-Encoding Standard
+  // encodings in the charset menu and in mailnews, assertions are futile.
+  if (!mCharacterSet.Equals(aCharSetID)) {
+    mCharacterSet = aCharSetID;
 
     int32_t n = mCharSetObservers.Length();
 
     for (int32_t i = 0; i < n; i++) {
       nsIObserver* observer = mCharSetObservers.ElementAt(i);
 
       observer->Observe(static_cast<nsIDocument *>(this), "charset",
-                        charset16.get());
+                        NS_ConvertASCIItoUTF16(aCharSetID).get());
     }
   }
 }
 
 nsresult
 nsDocument::AddCharSetObserver(nsIObserver* aObserver)
 {
   NS_ENSURE_ARG_POINTER(aObserver);
@@ -3837,26 +3836,26 @@ nsDocument::SetHeaderData(nsIAtom* aHead
       mReferrerPolicySet = true;
     }
   }
 
 }
 void
 nsDocument::TryChannelCharset(nsIChannel *aChannel,
                               int32_t& aCharsetSource,
-                              NotNull<const Encoding*>& aEncoding,
+                              nsACString& aCharset,
                               nsHtml5TreeOpExecutor* aExecutor)
 {
   if (aChannel) {
     nsAutoCString charsetVal;
     nsresult rv = aChannel->GetContentCharset(charsetVal);
     if (NS_SUCCEEDED(rv)) {
       const Encoding* preferred = Encoding::ForLabel(charsetVal);
       if (preferred) {
-        aEncoding = WrapNotNull(preferred);
+        preferred->Name(aCharset);
         aCharsetSource = kCharsetFromChannel;
         return;
       } else if (aExecutor && !charsetVal.IsEmpty()) {
         aExecutor->ComplainAboutBogusProtocolCharset(this);
       }
     }
   }
 }
@@ -6477,19 +6476,17 @@ nsDocument::GetCharacterSet(nsAString& a
 {
   nsIDocument::GetCharacterSet(aCharacterSet);
   return NS_OK;
 }
 
 void
 nsIDocument::GetCharacterSet(nsAString& aCharacterSet) const
 {
-  nsAutoCString charset;
-  GetDocumentCharacterSet()->Name(charset);
-  CopyASCIItoUTF16(charset, aCharacterSet);
+  CopyASCIItoUTF16(GetDocumentCharacterSet(), aCharacterSet);
 }
 
 NS_IMETHODIMP
 nsDocument::ImportNode(nsIDOMNode* aImportedNode,
                        bool aDeep,
                        uint8_t aArgc,
                        nsIDOMNode** aResult)
 {
@@ -6576,17 +6573,19 @@ nsIDocument::LoadBindingDocument(const n
 }
 
 void
 nsIDocument::LoadBindingDocument(const nsAString& aURI,
                                  const Maybe<nsIPrincipal*>& aSubjectPrincipal,
                                  ErrorResult& rv)
 {
   nsCOMPtr<nsIURI> uri;
-  rv = NS_NewURI(getter_AddRefs(uri), aURI, mCharacterSet, GetDocBaseURI());
+  rv = NS_NewURI(getter_AddRefs(uri), aURI,
+                 mCharacterSet.get(),
+                 GetDocBaseURI());
   if (rv.Failed()) {
     return;
   }
 
   // Note - This computation of subjectPrincipal isn't necessarily sensical.
   // It's just designed to preserve the old semantics during a mass-conversion
   // patch.
   nsCOMPtr<nsIPrincipal> subjectPrincipal =
@@ -9893,17 +9892,18 @@ nsDocument::ScrollToRef()
     } else {
       rv = NS_ERROR_FAILURE;
     }
 
     // If UTF-8 URI failed then try to assume the string as a
     // document's charset.
 
     if (NS_FAILED(rv)) {
-      auto encoding = GetDocumentCharacterSet();
+      const nsACString &docCharset = GetDocumentCharacterSet();
+      const Encoding* encoding = Encoding::ForName(docCharset);
 
       rv = encoding->DecodeWithoutBOMHandling(unescapedRef, ref);
 
       if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
         rv = shell->GoToAnchor(ref, mChangeScrollPosWhenScrollingToRef);
       }
     }
     if (NS_SUCCEEDED(rv)) {
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -420,21 +420,20 @@ public:
   virtual void SetBaseURI(nsIURI* aURI) override;
 
   /**
    * Get/Set the base target of a link in a document.
    */
   virtual void GetBaseTarget(nsAString &aBaseTarget) override;
 
   /**
-   * Set the document's character encoding. This will
+   * Return a standard name for the document's character set. This will
    * trigger a startDocumentLoad if necessary to answer the question.
    */
-  virtual void
-    SetDocumentCharacterSet(NotNull<const Encoding*> aEncoding) override;
+  virtual void SetDocumentCharacterSet(const nsACString& aCharSetID) override;
 
   /**
    * Add an observer that gets notified whenever the charset changes.
    */
   virtual nsresult AddCharSetObserver(nsIObserver* aObserver) override;
 
   /**
    * Remove a charset observer.
@@ -1045,17 +1044,17 @@ protected:
   void ReportEmptyGetElementByIdArg();
 
   void DispatchContentLoadedEvents();
 
   void RetrieveRelevantHeaders(nsIChannel *aChannel);
 
   void TryChannelCharset(nsIChannel *aChannel,
                          int32_t& aCharsetSource,
-                         NotNull<const Encoding*>& aEncoding,
+                         nsACString& aCharset,
                          nsHtml5TreeOpExecutor* aExecutor);
 
   // Call this before the document does something that will unbind all content.
   // That will stop us from doing a lot of work as each element is removed.
   void DestroyElementMaps();
 
   // Refreshes the hrefs of all the links in the document.
   void RefreshLinkHrefs();
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -267,25 +267,26 @@ nsFrameLoader::LoadFrame()
   }
 
   if (doc->IsLoadedAsInteractiveData()) {
     // XBL bindings doc shouldn't load sub-documents.
     return NS_OK;
   }
 
   nsCOMPtr<nsIURI> base_uri = mOwnerContent->GetBaseURI();
-  auto encoding = doc->GetDocumentCharacterSet();
+  const nsCString& doc_charset = doc->GetDocumentCharacterSet();
+  const char *charset = doc_charset.IsEmpty() ? nullptr : doc_charset.get();
 
   nsCOMPtr<nsIURI> uri;
-  nsresult rv = NS_NewURI(getter_AddRefs(uri), src, encoding, base_uri);
+  nsresult rv = NS_NewURI(getter_AddRefs(uri), src, charset, base_uri);
 
   // If the URI was malformed, try to recover by loading about:blank.
   if (rv == NS_ERROR_MALFORMED_URI) {
     rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_STRING("about:blank"),
-                   encoding, base_uri);
+                   charset, base_uri);
   }
 
   if (NS_SUCCEEDED(rv)) {
     rv = LoadURI(uri);
   }
 
   if (NS_FAILED(rv)) {
     FireErrorEvent();
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -13393,24 +13393,24 @@ nsGlobalWindow::SecurityCheckURL(const c
   JSAutoCompartment ac(cx, sourceWin->GetGlobalJSObject());
 
   // Resolve the baseURI, which could be relative to the calling window.
   //
   // Note the algorithm to get the base URI should match the one
   // used to actually kick off the load in nsWindowWatcher.cpp.
   nsCOMPtr<nsIDocument> doc = sourceWindow->GetDoc();
   nsIURI* baseURI = nullptr;
-  auto encoding = UTF_8_ENCODING; // default to utf-8
+  nsAutoCString charset(NS_LITERAL_CSTRING("UTF-8")); // default to utf-8
   if (doc) {
     baseURI = doc->GetDocBaseURI();
-    encoding = doc->GetDocumentCharacterSet();
+    charset = doc->GetDocumentCharacterSet();
   }
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_NewURI(getter_AddRefs(uri), nsDependentCString(aURL),
-                          encoding, baseURI);
+                          charset.get(), baseURI);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (NS_FAILED(nsContentUtils::GetSecurityManager()->
         CheckLoadURIFromScript(cx, uri))) {
     return NS_ERROR_FAILURE;
   }
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -29,17 +29,16 @@
 #include "mozilla/WeakPtr.h"
 #include "Units.h"
 #include "nsContentListDeclarations.h"
 #include "nsExpirationTracker.h"
 #include "nsClassHashtable.h"
 #include "mozilla/CORSMode.h"
 #include "mozilla/dom/DispatcherTrait.h"
 #include "mozilla/LinkedList.h"
-#include "mozilla/NotNull.h"
 #include "mozilla/SegmentedVector.h"
 #include "mozilla/StyleBackendType.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/UniquePtr.h"
 #include <bitset>                        // for member
 
 #ifdef MOZILLA_INTERNAL_API
@@ -100,17 +99,16 @@ class nsWindowSizes;
 class nsDOMCaretPosition;
 class nsViewportInfo;
 class nsIGlobalObject;
 struct nsCSSSelectorList;
 
 namespace mozilla {
 class AbstractThread;
 class CSSStyleSheet;
-class Encoding;
 class ErrorResult;
 class EventStates;
 class PendingAnimationTracker;
 class StyleSetHandle;
 template<typename> class OwningNonNull;
 struct URLExtraData;
 
 namespace css {
@@ -208,20 +206,16 @@ class nsContentList;
 
 // Document interface.  This is implemented by all document objects in
 // Gecko.
 class nsIDocument : public nsINode,
                     public mozilla::dom::DispatcherTrait
 {
   typedef mozilla::dom::GlobalObject GlobalObject;
 
-protected:
-  using Encoding = mozilla::Encoding;
-  template <typename T> using NotNull = mozilla::NotNull<T>;
-
 public:
   typedef mozilla::net::ReferrerPolicy ReferrerPolicyEnum;
   typedef mozilla::dom::Element Element;
   typedef mozilla::dom::FullscreenRequest FullscreenRequest;
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENT_IID)
 
 #ifdef MOZILLA_INTERNAL_API
@@ -505,25 +499,26 @@ public:
   virtual void GetBaseTarget(nsAString &aBaseTarget) = 0;
   void SetBaseTarget(const nsString& aBaseTarget) {
     mBaseTarget = aBaseTarget;
   }
 
   /**
    * Return a standard name for the document's character set.
    */
-  NotNull<const Encoding*> GetDocumentCharacterSet() const
+  const nsCString& GetDocumentCharacterSet() const
   {
     return mCharacterSet;
   }
 
   /**
-   * Set the document's character encoding.
+   * Set the document's character encoding. |aCharSetID| should be canonical.
+   * That is, callers are responsible for the charset alias resolution.
    */
-  virtual void SetDocumentCharacterSet(NotNull<const Encoding*> aEncoding) = 0;
+  virtual void SetDocumentCharacterSet(const nsACString& aCharSetID) = 0;
 
   int32_t GetDocumentCharacterSetSource() const
   {
     return mCharacterSetSource;
   }
 
   // This method MUST be called before SetDocumentCharacterSet if
   // you're planning to call both.
@@ -3059,17 +3054,17 @@ protected:
 
   // if nsMixedContentBlocker requires sending an HSTS priming request,
   // temporarily store that in the document so that it can be propogated to the
   // LoadInfo and eventually the HTTP Channel
   nsDataHashtable<nsURIHashKey, HSTSPrimingState> mHSTSPrimingURIList;
 
   mozilla::WeakPtr<nsDocShell> mDocumentContainer;
 
-  NotNull<const Encoding*> mCharacterSet;
+  nsCString mCharacterSet;
   int32_t mCharacterSetSource;
 
   // This is just a weak pointer; the parent document owns its children.
   nsIDocument* mParentDocument;
 
   // A reference to the element last returned from GetRootElement().
   mozilla::dom::Element* mCachedRootElement;
 
--- a/dom/base/nsImageLoadingContent.cpp
+++ b/dom/base/nsImageLoadingContent.cpp
@@ -1123,22 +1123,22 @@ nsImageLoadingContent::StringToURI(const
   NS_PRECONDITION(aDocument, "Must have a document");
   NS_PRECONDITION(aURI, "Null out param");
 
   // (1) Get the base URI
   nsIContent* thisContent = AsContent();
   nsCOMPtr<nsIURI> baseURL = thisContent->GetBaseURI();
 
   // (2) Get the charset
-  auto encoding = aDocument->GetDocumentCharacterSet();
+  const nsCString& charset = aDocument->GetDocumentCharacterSet();
 
   // (3) Construct the silly thing
   return NS_NewURI(aURI,
                    aSpec,
-                   encoding,
+                   charset.IsEmpty() ? nullptr : charset.get(),
                    baseURL,
                    nsContentUtils::GetIOService());
 }
 
 nsresult
 nsImageLoadingContent::FireEvent(const nsAString& aEventType, bool aIsCancelable)
 {
   if (nsContentUtils::DocumentInactiveForImageLoads(GetOurOwnerDoc())) {
--- a/dom/base/nsReferencedElement.cpp
+++ b/dom/base/nsReferencedElement.cpp
@@ -28,20 +28,18 @@ nsReferencedElement::Reset(nsIContent* a
   nsAutoCString refPart;
   aURI->GetRef(refPart);
   // Unescape %-escapes in the reference. The result will be in the
   // origin charset of the URL, hopefully...
   NS_UnescapeURL(refPart);
 
   nsAutoCString charset;
   aURI->GetOriginCharset(charset);
-  auto encoding = Encoding::ForLabelNoReplacement(charset);
-  if (!encoding) {
-    encoding = UTF_8_ENCODING;
-  }
+  const Encoding* encoding = charset.IsEmpty() ?
+    UTF_8_ENCODING : Encoding::ForName(charset);
   nsAutoString ref;
   nsresult rv = encoding->DecodeWithoutBOMHandling(refPart, ref);
   if (NS_FAILED(rv) || ref.IsEmpty()) {
     return;
   }
   rv = NS_OK;
 
   // Get the current document
--- a/dom/encoding/FallbackEncoding.cpp
+++ b/dom/encoding/FallbackEncoding.cpp
@@ -31,87 +31,86 @@ static constexpr nsUConvProp nonParticip
 };
 
 NS_IMPL_ISUPPORTS(FallbackEncoding, nsIObserver)
 
 FallbackEncoding* FallbackEncoding::sInstance = nullptr;
 bool FallbackEncoding::sGuessFallbackFromTopLevelDomain = true;
 
 FallbackEncoding::FallbackEncoding()
-  : mFallback(nullptr)
 {
   MOZ_ASSERT(!FallbackEncoding::sInstance,
              "Singleton already exists.");
 }
 
-NotNull<const Encoding*>
-FallbackEncoding::Get()
+void
+FallbackEncoding::Get(nsACString& aFallback)
 {
-  if (mFallback) {
-    return WrapNotNull(mFallback);
+  if (!mFallback.IsEmpty()) {
+    aFallback = mFallback;
+    return;
   }
 
   const nsAdoptingCString& override =
     Preferences::GetCString("intl.charset.fallback.override");
   // Don't let the user break things by setting the override to unreasonable
   // values via about:config
-  auto encoding = Encoding::ForLabel(override);
+  const Encoding* encoding = Encoding::ForLabel(override);
   if (!encoding || !encoding->IsAsciiCompatible() ||
       encoding == UTF_8_ENCODING) {
-    mFallback = nullptr;
+    mFallback.Truncate();
   } else {
-    mFallback = encoding;
+    encoding->Name(mFallback);
   }
 
-  if (mFallback) {
-    return WrapNotNull(mFallback);
+  if (!mFallback.IsEmpty()) {
+    aFallback = mFallback;
+    return;
   }
 
   nsAutoCString locale;
   LocaleService::GetInstance()->GetAppLocaleAsLangTag(locale);
 
   // Let's lower case the string just in case unofficial language packs
   // don't stick to conventions.
   ToLowerCase(locale); // ASCII lowercasing with CString input!
 
   // Special case Traditional Chinese before throwing away stuff after the
   // language itself. Today we only ship zh-TW, but be defensive about
   // possible future values.
   if (locale.EqualsLiteral("zh-tw") ||
       locale.EqualsLiteral("zh-hk") ||
       locale.EqualsLiteral("zh-mo") ||
       locale.EqualsLiteral("zh-hant")) {
-    mFallback = BIG5_ENCODING;
-    return WrapNotNull(mFallback);
+    mFallback.AssignLiteral("Big5");
+    aFallback = mFallback;
+    return;
   }
 
   // Throw away regions and other variants to accommodate weird stuff seen
   // in telemetry--apparently unofficial language packs.
   int32_t index = locale.FindChar('-');
   if (index >= 0) {
     locale.Truncate(index);
   }
 
-  nsAutoCString fallback;
   if (NS_FAILED(nsUConvPropertySearch::SearchPropertyValue(
-      localesFallbacks, ArrayLength(localesFallbacks), locale, fallback))) {
-    mFallback = WINDOWS_1252_ENCODING;
-  } else {
-    mFallback = Encoding::ForName(fallback);
+      localesFallbacks, ArrayLength(localesFallbacks), locale, mFallback))) {
+    mFallback.AssignLiteral("windows-1252");
   }
 
-  return WrapNotNull(mFallback);
+  aFallback = mFallback;
 }
 
-NotNull<const Encoding*>
-FallbackEncoding::FromLocale()
+void
+FallbackEncoding::FromLocale(nsACString& aFallback)
 {
   MOZ_ASSERT(FallbackEncoding::sInstance,
              "Using uninitialized fallback cache.");
-  return FallbackEncoding::sInstance->Get();
+  FallbackEncoding::sInstance->Get(aFallback);
 }
 
 // PrefChangedFunc
 void
 FallbackEncoding::PrefChanged(const char*, void*)
 {
   MOZ_ASSERT(FallbackEncoding::sInstance,
              "Pref callback called with null fallback cache.");
@@ -165,21 +164,20 @@ FallbackEncoding::IsParticipatingTopLeve
   nsAutoCString dummy;
   return NS_FAILED(nsUConvPropertySearch::SearchPropertyValue(
       nonParticipatingDomains,
       ArrayLength(nonParticipatingDomains),
       aTLD,
       dummy));
 }
 
-NotNull<const Encoding*>
-FallbackEncoding::FromTopLevelDomain(const nsACString& aTLD)
+void
+FallbackEncoding::FromTopLevelDomain(const nsACString& aTLD,
+                                     nsACString& aFallback)
 {
-  nsAutoCString fallback;
   if (NS_FAILED(nsUConvPropertySearch::SearchPropertyValue(
-      domainsFallbacks, ArrayLength(domainsFallbacks), aTLD, fallback))) {
-    return WINDOWS_1252_ENCODING;
+      domainsFallbacks, ArrayLength(domainsFallbacks), aTLD, aFallback))) {
+    aFallback.AssignLiteral("windows-1252");
   }
-  return Encoding::ForName(fallback);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/encoding/FallbackEncoding.h
+++ b/dom/encoding/FallbackEncoding.h
@@ -2,22 +2,20 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #ifndef mozilla_dom_FallbackEncoding_h_
 #define mozilla_dom_FallbackEncoding_h_
 
-#include "mozilla/NotNull.h"
 #include "nsIObserver.h"
 #include "nsString.h"
 
 namespace mozilla {
-class Encoding;
 namespace dom {
 
 class FallbackEncoding : public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
@@ -27,34 +25,34 @@ public:
   static bool sGuessFallbackFromTopLevelDomain;
 
   /**
    * Gets the locale-dependent fallback encoding for legacy HTML and plain
    * text content.
    *
    * @param aFallback the outparam for the fallback encoding
    */
-  static NotNull<const Encoding*> FromLocale();
+  static void FromLocale(nsACString& aFallback);
 
   /**
    * Checks if it is appropriate to call FromTopLevelDomain() for a given TLD.
    *
    * @param aTLD the top-level domain (in Punycode)
    * @return true if OK to call FromTopLevelDomain()
    */
   static bool IsParticipatingTopLevelDomain(const nsACString& aTLD);
 
   /**
    * Gets a top-level domain-depedendent fallback encoding for legacy HTML
    * and plain text content
    *
    * @param aTLD the top-level domain (in Punycode)
    * @param aFallback the outparam for the fallback encoding
    */
-  static NotNull<const Encoding*> FromTopLevelDomain(const nsACString& aTLD);
+  static void FromTopLevelDomain(const nsACString& aTLD, nsACString& aFallback);
 
   // public API ends here!
 
   /**
    * Allocate sInstance used by FromLocale().
    * To be called from nsLayoutStatics only.
    */
   static void Initialize();
@@ -75,27 +73,27 @@ private:
   FallbackEncoding();
   virtual ~FallbackEncoding() {};
 
   /**
    * Invalidates the cache.
    */
   void Invalidate()
   {
-    mFallback = nullptr;
+    mFallback.Truncate();
   }
 
   static void PrefChanged(const char*, void*);
 
   /**
    * Gets the fallback encoding label.
    * @param aFallback the fallback encoding
    */
-  NotNull<const Encoding*> Get();
+  void Get(nsACString& aFallback);
 
-  const Encoding* mFallback;
+  nsCString mFallback;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_FallbackEncoding_h_
 
--- a/dom/html/HTMLFormSubmission.cpp
+++ b/dom/html/HTMLFormSubmission.cpp
@@ -882,17 +882,17 @@ GetSubmitEncoding(nsGenericHTMLElement* 
       }
       offset = spPos + 1;
     } while (spPos != -1);
   }
   // if there are no accept-charset or all the charset are not supported
   // Get the charset from document
   nsIDocument* doc = aForm->GetComposedDoc();
   if (doc) {
-    return doc->GetDocumentCharacterSet();
+    return Encoding::ForName(doc->GetDocumentCharacterSet());
   }
   return UTF_8_ENCODING;
 }
 
 void
 GetEnumAttr(nsGenericHTMLElement* aContent,
             nsIAtom* atom, int32_t* aValue)
 {
--- a/dom/html/MediaDocument.cpp
+++ b/dom/html/MediaDocument.cpp
@@ -166,26 +166,27 @@ MediaDocument::StartDocumentLoad(const c
   // in UTF-8, we don't lose anything because the default empty value is 
   // considered synonymous with UTF-8. 
     
   nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
 
   // not being able to set the charset is not critical.
   NS_ENSURE_TRUE(docShell, NS_OK); 
 
-  const Encoding* encoding;
+  nsAutoCString charset;
   int32_t source;
   nsCOMPtr<nsIPrincipal> principal;
   // opening in a new tab
-  docShell->GetParentCharset(encoding, &source, getter_AddRefs(principal));
+  docShell->GetParentCharset(charset, &source, getter_AddRefs(principal));
 
-  if (encoding && encoding != UTF_8_ENCODING &&
+  if (!charset.IsEmpty() &&
+      !charset.EqualsLiteral("UTF-8") &&
       NodePrincipal()->Equals(principal)) {
     SetDocumentCharacterSetSource(source);
-    SetDocumentCharacterSet(WrapNotNull(encoding));
+    SetDocumentCharacterSet(charset);
   }
 
   return NS_OK;
 }
 
 void
 MediaDocument::BecomeInteractive()
 {
@@ -293,24 +294,21 @@ MediaDocument::GetFileName(nsAString& aR
   nsAutoCString docCharset;
   // Now that the charset is set in |StartDocumentLoad| to the charset of
   // the document viewer instead of a bogus value ("windows-1252" set in
   // |nsDocument|'s ctor), the priority is given to the current charset. 
   // This is necessary to deal with a media document being opened in a new 
   // window or a new tab, in which case |originCharset| of |nsIURI| is not 
   // reliable.
   if (mCharacterSetSource != kCharsetUninitialized) {  
-    mCharacterSet->Name(docCharset);
+    docCharset = mCharacterSet;
   } else {  
     // resort to |originCharset|
     url->GetOriginCharset(docCharset);
-    auto encoding = Encoding::ForLabelNoReplacement(docCharset);
-    if (encoding) {
-      SetDocumentCharacterSet(WrapNotNull(encoding));
-    }
+    SetDocumentCharacterSet(docCharset);
   }
 
   nsresult rv;
   nsCOMPtr<nsITextToSubURI> textToSubURI = 
     do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
   if (NS_SUCCEEDED(rv)) {
     // UnEscapeURIForUI always succeeds
     textToSubURI->UnEscapeURIForUI(docCharset, fileName, aResult);
--- a/dom/html/nsHTMLContentSink.cpp
+++ b/dom/html/nsHTMLContentSink.cpp
@@ -131,17 +131,17 @@ public:
   // nsIContentSink
   NS_IMETHOD WillParse(void) override;
   NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override;
   NS_IMETHOD DidBuildModel(bool aTerminated) override;
   NS_IMETHOD WillInterrupt(void) override;
   NS_IMETHOD WillResume(void) override;
   NS_IMETHOD SetParser(nsParserBase* aParser) override;
   virtual void FlushPendingNotifications(FlushType aType) override;
-  virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override;
+  NS_IMETHOD SetDocumentCharset(nsACString& aCharset) override;
   virtual nsISupports *GetTarget() override;
   virtual bool IsScriptExecuting() override;
 
   // nsIHTMLContentSink
   NS_IMETHOD OpenContainer(ElementType aNodeType) override;
   NS_IMETHOD CloseContainer(ElementType aTag) override;
 
 protected:
@@ -1082,20 +1082,21 @@ HTMLContentSink::FlushTags()
   if (!mNotifiedRootInsertion) {
     NotifyRootInsertion();
     return NS_OK;
   }
 
   return mCurrentContext ? mCurrentContext->FlushTags() : NS_OK;
 }
 
-void
-HTMLContentSink::SetDocumentCharset(NotNull<const Encoding*> aEncoding)
+NS_IMETHODIMP
+HTMLContentSink::SetDocumentCharset(nsACString& aCharset)
 {
   MOZ_ASSERT_UNREACHABLE("<meta charset> case doesn't occur with about:blank");
+  return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsISupports *
 HTMLContentSink::GetTarget()
 {
   return mDocument;
 }
 
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -159,22 +159,16 @@ IsAsciiCompatible(const nsACString& aPre
            aPreferredName.LowerCaseEqualsLiteral("utf-16be") ||
            aPreferredName.LowerCaseEqualsLiteral("utf-16le") ||
            aPreferredName.LowerCaseEqualsLiteral("replacement") ||
            aPreferredName.LowerCaseEqualsLiteral("hz-gb-2312") ||
            aPreferredName.LowerCaseEqualsLiteral("utf-7") ||
            aPreferredName.LowerCaseEqualsLiteral("x-imap4-modified-utf7"));
 }
 
-static bool
-IsAsciiCompatible(const Encoding* aEncoding)
-{
-  return aEncoding->IsAsciiCompatible() || aEncoding == ISO_2022_JP_ENCODING;
-}
-
 nsresult
 NS_NewHTMLDocument(nsIDocument** aInstancePtrResult, bool aLoadedAsData)
 {
   RefPtr<nsHTMLDocument> doc = new nsHTMLDocument();
 
   nsresult rv = doc->Init();
 
   if (NS_FAILED(rv)) {
@@ -287,94 +281,92 @@ nsHTMLDocument::ResetToURI(nsIURI *aURI,
   // Make the content type default to "text/html", we are a HTML
   // document, after all. Once we start getting data, this may be
   // changed.
   SetContentTypeInternal(nsDependentCString("text/html"));
 }
 
 void
 nsHTMLDocument::TryHintCharset(nsIContentViewer* aCv,
-                               int32_t& aCharsetSource,
-                               NotNull<const Encoding*>& aEncoding)
+                               int32_t& aCharsetSource, nsACString& aCharset)
 {
   if (aCv) {
     int32_t requestCharsetSource;
     nsresult rv = aCv->GetHintCharacterSetSource(&requestCharsetSource);
 
     if(NS_SUCCEEDED(rv) && kCharsetUninitialized != requestCharsetSource) {
       nsAutoCString requestCharset;
       rv = aCv->GetHintCharacterSet(requestCharset);
       aCv->SetHintCharacterSetSource((int32_t)(kCharsetUninitialized));
 
-      if (requestCharsetSource <= aCharsetSource)
+      if(requestCharsetSource <= aCharsetSource)
         return;
 
-      if (NS_SUCCEEDED(rv) && !requestCharset.IsEmpty()) {
-        auto encoding = Encoding::ForName(requestCharset);
-        if (IsAsciiCompatible(encoding)) {
-          aCharsetSource = requestCharsetSource;
-          aEncoding = encoding;
-        }
+      if(NS_SUCCEEDED(rv) && IsAsciiCompatible(requestCharset)) {
+        aCharsetSource = requestCharsetSource;
+        aCharset = requestCharset;
+
         return;
       }
     }
   }
   return;
 }
 
 
 void
 nsHTMLDocument::TryUserForcedCharset(nsIContentViewer* aCv,
                                      nsIDocShell*  aDocShell,
                                      int32_t& aCharsetSource,
-                                     NotNull<const Encoding*>& aEncoding)
+                                     nsACString& aCharset)
 {
   nsresult rv = NS_OK;
 
   if(kCharsetFromUserForced <= aCharsetSource)
     return;
 
-  // mCharacterSet not updated yet for channel, so check aEncoding, too.
-  if (WillIgnoreCharsetOverride() || !IsAsciiCompatible(aEncoding)) {
+  // mCharacterSet not updated yet for channel, so check aCharset, too.
+  if (WillIgnoreCharsetOverride() || !IsAsciiCompatible(aCharset)) {
     return;
   }
 
   nsAutoCString forceCharsetFromDocShell;
   if (aCv) {
     // XXX mailnews-only
     rv = aCv->GetForceCharacterSet(forceCharsetFromDocShell);
   }
 
   if(NS_SUCCEEDED(rv) &&
      !forceCharsetFromDocShell.IsEmpty() &&
      IsAsciiCompatible(forceCharsetFromDocShell)) {
-    aEncoding = Encoding::ForName(forceCharsetFromDocShell);
+    aCharset = forceCharsetFromDocShell;
     aCharsetSource = kCharsetFromUserForced;
     return;
   }
 
   if (aDocShell) {
     // This is the Character Encoding menu code path in Firefox
-    auto encoding = nsDocShell::Cast(aDocShell)->GetForcedCharset();
-
-    if (encoding) {
-      if (!IsAsciiCompatible(encoding)) {
+    nsAutoCString charset;
+    rv = aDocShell->GetForcedCharset(charset);
+
+    if (NS_SUCCEEDED(rv) && !charset.IsEmpty()) {
+      if (!IsAsciiCompatible(charset)) {
         return;
       }
-      aEncoding = WrapNotNull(encoding);
+      aCharset = charset;
       aCharsetSource = kCharsetFromUserForced;
       aDocShell->SetForcedCharset(NS_LITERAL_CSTRING(""));
     }
   }
 }
 
 void
 nsHTMLDocument::TryCacheCharset(nsICachingChannel* aCachingChannel,
                                 int32_t& aCharsetSource,
-                                NotNull<const Encoding*>& aEncoding)
+                                nsACString& aCharset)
 {
   nsresult rv;
 
   if (kCharsetFromCache <= aCharsetSource) {
     return;
   }
 
   nsCString cachedCharset;
@@ -392,72 +384,72 @@ nsHTMLDocument::TryCacheCharset(nsICachi
     return;
   }
   // Check IsAsciiCompatible() even in the cache case, because the value
   // might be stale and in the case of a stale charset that is not a rough
   // ASCII superset, the parser has no way to recover.
   if (!encoding->IsAsciiCompatible() && encoding != ISO_2022_JP_ENCODING) {
     return;
   }
-  aEncoding = WrapNotNull(encoding);
+  encoding->Name(cachedCharset);
+  aCharset = cachedCharset;
   aCharsetSource = kCharsetFromCache;
 }
 
 void
 nsHTMLDocument::TryParentCharset(nsIDocShell*  aDocShell,
                                  int32_t& aCharsetSource,
-                                 NotNull<const Encoding*>& aEncoding)
+                                 nsACString& aCharset)
 {
   if (!aDocShell) {
     return;
   }
   if (aCharsetSource >= kCharsetFromParentForced) {
     return;
   }
 
   int32_t parentSource;
-  const Encoding* parentCharset;
+  nsAutoCString parentCharset;
   nsCOMPtr<nsIPrincipal> parentPrincipal;
   aDocShell->GetParentCharset(parentCharset,
                               &parentSource,
                               getter_AddRefs(parentPrincipal));
-  if (!parentCharset) {
+  if (parentCharset.IsEmpty()) {
     return;
   }
   if (kCharsetFromParentForced == parentSource ||
       kCharsetFromUserForced == parentSource) {
     if (WillIgnoreCharsetOverride() ||
-        !IsAsciiCompatible(aEncoding) || // if channel said UTF-16
+        !IsAsciiCompatible(aCharset) || // if channel said UTF-16
         !IsAsciiCompatible(parentCharset)) {
       return;
     }
-    aEncoding = WrapNotNull(parentCharset);
+    aCharset.Assign(parentCharset);
     aCharsetSource = kCharsetFromParentForced;
     return;
   }
 
   if (aCharsetSource >= kCharsetFromParentFrame) {
     return;
   }
 
   if (kCharsetFromCache <= parentSource) {
     // Make sure that's OK
     if (!NodePrincipal()->Equals(parentPrincipal) ||
         !IsAsciiCompatible(parentCharset)) {
       return;
     }
 
-    aEncoding = WrapNotNull(parentCharset);
+    aCharset.Assign(parentCharset);
     aCharsetSource = kCharsetFromParentFrame;
   }
 }
 
 void
-nsHTMLDocument::TryTLD(int32_t& aCharsetSource,
-                       NotNull<const Encoding*>& aEncoding)
+nsHTMLDocument::TryTLD(int32_t& aCharsetSource, nsACString& aCharset)
 {
   if (aCharsetSource >= kCharsetFromTopLevelDomain) {
     return;
   }
   if (!FallbackEncoding::sGuessFallbackFromTopLevelDomain) {
     return;
   }
   if (!mDocumentURI) {
@@ -503,42 +495,39 @@ nsHTMLDocument::TryTLD(int32_t& aCharset
       seenNonDigit = true;
       break;
     }
   }
   if (!seenNonDigit) {
     return;
   }
   aCharsetSource = kCharsetFromTopLevelDomain;
-  aEncoding = FallbackEncoding::FromTopLevelDomain(tld);
+  FallbackEncoding::FromTopLevelDomain(tld, aCharset);
 }
 
 void
-nsHTMLDocument::TryFallback(int32_t& aCharsetSource,
-                            NotNull<const Encoding*>& aEncoding)
+nsHTMLDocument::TryFallback(int32_t& aCharsetSource, nsACString& aCharset)
 {
   if (kCharsetFromFallback <= aCharsetSource)
     return;
 
   aCharsetSource = kCharsetFromFallback;
-  aEncoding = FallbackEncoding::FromLocale();
+  FallbackEncoding::FromLocale(aCharset);
 }
 
 void
-nsHTMLDocument::SetDocumentCharacterSet(NotNull<const Encoding*> aEncoding)
+nsHTMLDocument::SetDocumentCharacterSet(const nsACString& aCharSetID)
 {
-  nsDocument::SetDocumentCharacterSet(aEncoding);
+  nsDocument::SetDocumentCharacterSet(aCharSetID);
   // Make sure to stash this charset on our channel as needed if it's a wyciwyg
   // channel.
   nsCOMPtr<nsIWyciwygChannel> wyciwygChannel = do_QueryInterface(mChannel);
   if (wyciwygChannel) {
-    nsAutoCString charset;
-    aEncoding->Name(charset);
     wyciwygChannel->SetCharsetAndSource(GetDocumentCharacterSetSource(),
-                                        charset);
+                                        aCharSetID);
   }
 }
 
 nsresult
 nsHTMLDocument::StartDocumentLoad(const char* aCommand,
                                   nsIChannel* aChannel,
                                   nsILoadGroup* aLoadGroup,
                                   nsISupports* aContainer,
@@ -677,45 +666,48 @@ nsHTMLDocument::StartDocumentLoad(const 
   nsAutoCString urlSpec;
   uri->GetSpec(urlSpec);
 #ifdef DEBUG_charset
   printf("Determining charset for %s\n", urlSpec.get());
 #endif
 
   // These are the charset source and charset for our document
   int32_t charsetSource;
-  auto encoding = UTF_8_ENCODING;
+  nsAutoCString charset;
 
   // These are the charset source and charset for the parser.  This can differ
   // from that for the document if the channel is a wyciwyg channel.
   int32_t parserCharsetSource;
-  auto parserCharset = UTF_8_ENCODING;
+  nsAutoCString parserCharset;
 
   nsCOMPtr<nsIWyciwygChannel> wyciwygChannel;
 
   // For error reporting and referrer policy setting
   nsHtml5TreeOpExecutor* executor = nullptr;
   if (loadAsHtml5) {
     executor = static_cast<nsHtml5TreeOpExecutor*> (mParser->GetContentSink());
     if (mReferrerPolicySet) {
       // CSP may have set the referrer policy, so a speculative parser should
       // start with the new referrer policy.
       executor->SetSpeculationReferrerPolicy(static_cast<ReferrerPolicy>(mReferrerPolicy));
     }
   }
 
   if (forceUtf8) {
     charsetSource = kCharsetFromUtf8OnlyMime;
+    charset.AssignLiteral("UTF-8");
     parserCharsetSource = charsetSource;
+    parserCharset = charset;
   } else if (!IsHTMLDocument() || !docShell) { // no docshell for text/html XHR
     charsetSource = IsHTMLDocument() ? kCharsetFromFallback
                                      : kCharsetFromDocTypeDefault;
-    TryChannelCharset(aChannel, charsetSource, encoding, executor);
-    parserCharset = encoding;
+    charset.AssignLiteral("UTF-8");
+    TryChannelCharset(aChannel, charsetSource, charset, executor);
     parserCharsetSource = charsetSource;
+    parserCharset = charset;
   } else {
     NS_ASSERTION(docShell, "Unexpected null value");
 
     charsetSource = kCharsetUninitialized;
     wyciwygChannel = do_QueryInterface(aChannel);
 
     // The following will try to get the character encoding from various
     // sources. Each Try* function will return early if the source is already
@@ -729,83 +721,76 @@ nsHTMLDocument::StartDocumentLoad(const 
     if (!wyciwygChannel) {
       // Otherwise, try the channel's charset (e.g., charset from HTTP
       // "Content-Type" header) first. This way, we get to reject overrides in
       // TryParentCharset and TryUserForcedCharset if the channel said UTF-16.
       // This is to avoid socially engineered XSS by adding user-supplied
       // content to a UTF-16 site such that the byte have a dangerous
       // interpretation as ASCII and the user can be lured to using the
       // charset menu.
-      TryChannelCharset(aChannel, charsetSource, encoding, executor);
+      TryChannelCharset(aChannel, charsetSource, charset, executor);
     }
 
-    TryUserForcedCharset(cv, docShell, charsetSource, encoding);
-
-    TryHintCharset(cv, charsetSource, encoding); // XXX mailnews-only
-    TryParentCharset(docShell, charsetSource, encoding);
+    TryUserForcedCharset(cv, docShell, charsetSource, charset);
+
+    TryHintCharset(cv, charsetSource, charset); // XXX mailnews-only
+    TryParentCharset(docShell, charsetSource, charset);
 
     if (cachingChan && !urlSpec.IsEmpty()) {
-      TryCacheCharset(cachingChan, charsetSource, encoding);
+      TryCacheCharset(cachingChan, charsetSource, charset);
     }
 
-    TryTLD(charsetSource, encoding);
-    TryFallback(charsetSource, encoding);
+    TryTLD(charsetSource, charset);
+    TryFallback(charsetSource, charset);
 
     if (wyciwygChannel) {
       // We know for sure that the parser needs to be using UTF16.
-      parserCharset = UTF_16LE_ENCODING;
+      parserCharset = "UTF-16LE";
       parserCharsetSource = charsetSource < kCharsetFromChannel ?
         kCharsetFromChannel : charsetSource;
 
       nsAutoCString cachedCharset;
       int32_t cachedSource;
       rv = wyciwygChannel->GetCharsetAndSource(&cachedSource, cachedCharset);
       if (NS_SUCCEEDED(rv)) {
         if (cachedSource > charsetSource) {
-          auto cachedEncoding = Encoding::ForLabel(cachedCharset);
-          if (!cachedEncoding && cachedCharset.EqualsLiteral("replacement")) {
-            cachedEncoding = REPLACEMENT_ENCODING;
-          }
-          if (cachedEncoding) {
-            charsetSource = cachedSource;
-            encoding = WrapNotNull(cachedEncoding);
-          }
+          charsetSource = cachedSource;
+          charset = cachedCharset;
         }
       } else {
         // Don't propagate this error.
         rv = NS_OK;
       }
+
     } else {
-      parserCharset = encoding;
+      parserCharset = charset;
       parserCharsetSource = charsetSource;
     }
   }
 
   SetDocumentCharacterSetSource(charsetSource);
-  SetDocumentCharacterSet(encoding);
+  SetDocumentCharacterSet(charset);
 
   if (cachingChan) {
-    NS_ASSERTION(encoding == parserCharset,
+    NS_ASSERTION(charset == parserCharset,
                  "How did those end up different here?  wyciwyg channels are "
                  "not nsICachingChannel");
-    nsAutoCString charset;
-    encoding->Name(charset);
     rv = cachingChan->SetCacheTokenCachedCharset(charset);
     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "cannot SetMetaDataElement");
     rv = NS_OK; // don't propagate error
   }
 
   // Set the parser as the stream listener for the document loader...
   rv = NS_OK;
   nsCOMPtr<nsIStreamListener> listener = mParser->GetStreamListener();
   listener.forget(aDocListener);
 
 #ifdef DEBUG_charset
   printf(" charset = %s source %d\n",
-         charset.get(), charsetSource);
+        charset.get(), charsetSource);
 #endif
   mParser->SetDocumentCharset(parserCharset, parserCharsetSource);
   mParser->SetCommand(aCommand);
 
   if (!IsHTMLDocument()) {
     MOZ_ASSERT(!loadAsHtml5);
     nsCOMPtr<nsIXMLContentSink> xmlsink;
     NS_NewXMLContentSink(getter_AddRefs(xmlsink), this, uri,
@@ -2426,19 +2411,18 @@ nsHTMLDocument::CreateAndAddWyciwygChann
 
   mWyciwygChannel = do_QueryInterface(channel);
 
   mWyciwygChannel->SetSecurityInfo(mSecurityInfo);
 
   // Note: we want to treat this like a "previous document" hint so that,
   // e.g. a <meta> tag in the document.write content can override it.
   SetDocumentCharacterSetSource(kCharsetFromHintPrevDoc);
-  nsAutoCString charset;
-  GetDocumentCharacterSet()->Name(charset);
-  mWyciwygChannel->SetCharsetAndSource(kCharsetFromHintPrevDoc, charset);
+  mWyciwygChannel->SetCharsetAndSource(kCharsetFromHintPrevDoc,
+                                       GetDocumentCharacterSet());
 
   // Inherit load flags from the original document's channel
   channel->SetLoadFlags(mLoadFlags);
 
   nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
 
   // Use the Parent document's loadgroup to trigger load notifications
   if (loadGroup && channel) {
@@ -3753,18 +3737,17 @@ nsHTMLDocument::WillIgnoreCharsetOverrid
 {
   if (mType != eHTML) {
     MOZ_ASSERT(mType == eXHTML);
     return true;
   }
   if (mCharacterSetSource >= kCharsetFromByteOrderMark) {
     return true;
   }
-  if (!mCharacterSet->IsAsciiCompatible() &&
-      mCharacterSet != ISO_2022_JP_ENCODING) {
+  if (!IsAsciiCompatible(mCharacterSet)) {
     return true;
   }
   nsCOMPtr<nsIWyciwygChannel> wyciwyg = do_QueryInterface(mChannel);
   if (wyciwyg) {
     return true;
   }
   nsIURI* uri = GetOriginalURI();
   if (uri) {
--- a/dom/html/nsHTMLDocument.h
+++ b/dom/html/nsHTMLDocument.h
@@ -316,34 +316,31 @@ protected:
 
   /** # of forms in the document, synchronously set */
   int32_t mNumForms;
 
   static uint32_t gWyciwygSessionCnt;
 
   static void TryHintCharset(nsIContentViewer* aContentViewer,
                              int32_t& aCharsetSource,
-                             NotNull<const Encoding*>& aEncoding);
+                             nsACString& aCharset);
   void TryUserForcedCharset(nsIContentViewer* aCv,
                             nsIDocShell*  aDocShell,
                             int32_t& aCharsetSource,
-                            NotNull<const Encoding*>& aEncoding);
+                            nsACString& aCharset);
   static void TryCacheCharset(nsICachingChannel* aCachingChannel,
-                              int32_t& aCharsetSource,
-                              NotNull<const Encoding*>& aEncoding);
+                                int32_t& aCharsetSource,
+                                nsACString& aCharset);
   void TryParentCharset(nsIDocShell*  aDocShell,
-                        int32_t& charsetSource,
-                        NotNull<const Encoding*>& aEncoding);
-  void TryTLD(int32_t& aCharsetSource, NotNull<const Encoding*>& aCharset);
-  static void TryFallback(int32_t& aCharsetSource,
-                          NotNull<const Encoding*>& aEncoding);
+                        int32_t& charsetSource, nsACString& aCharset);
+  void TryTLD(int32_t& aCharsetSource, nsACString& aCharset);
+  static void TryFallback(int32_t& aCharsetSource, nsACString& aCharset);
 
   // Override so we can munge the charset on our wyciwyg channel as needed.
-  virtual void
-    SetDocumentCharacterSet(NotNull<const Encoding*> aEncoding) override;
+  virtual void SetDocumentCharacterSet(const nsACString& aCharSetID) override;
 
   // Tracks if we are currently processing any document.write calls (either
   // implicit or explicit). Note that if a write call writes out something which
   // would block the parser, then mWriteLevel will be incorrect until the parser
   // finishes processing that script.
   uint32_t mWriteLevel;
 
   // Load flags of the document's channel
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "mozilla/dom/Notification.h"
 
-#include "mozilla/Encoding.h"
 #include "mozilla/JSONWriter.h"
 #include "mozilla/Move.h"
 #include "mozilla/OwningNonNull.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
 
@@ -1918,44 +1917,44 @@ Notification::ResolveIconAndSoundURL(nsS
   // XXXnsm If I understand correctly, the character encoding for resolving
   // URIs in new specs is dictated by the URL spec, which states that unless
   // the URL parser is passed an override encoding, the charset to be used is
   // UTF-8. The new Notification icon/sound specification just says to use the
   // Fetch API, where the Request constructor defers to URL parsing specifying
   // the API base URL and no override encoding. So we've to use UTF-8 on
   // workers, but for backwards compat keeping it document charset on main
   // thread.
-  auto encoding = UTF_8_ENCODING;
+  const char* charset = "UTF-8";
 
   if (mWorkerPrivate) {
     baseUri = mWorkerPrivate->GetBaseURI();
   } else {
     nsIDocument* doc = GetOwner() ? GetOwner()->GetExtantDoc() : nullptr;
     if (doc) {
       baseUri = doc->GetBaseURI();
-      encoding = doc->GetDocumentCharacterSet();
+      charset = doc->GetDocumentCharacterSet().get();
     } else {
       NS_WARNING("No document found for main thread notification!");
       return NS_ERROR_FAILURE;
     }
   }
 
   if (baseUri) {
     if (mIconUrl.Length() > 0) {
       nsCOMPtr<nsIURI> srcUri;
-      rv = NS_NewURI(getter_AddRefs(srcUri), mIconUrl, encoding, baseUri);
+      rv = NS_NewURI(getter_AddRefs(srcUri), mIconUrl, charset, baseUri);
       if (NS_SUCCEEDED(rv)) {
         nsAutoCString src;
         srcUri->GetSpec(src);
         iconUrl = NS_ConvertUTF8toUTF16(src);
       }
     }
     if (mBehavior.mSoundFile.Length() > 0) {
       nsCOMPtr<nsIURI> srcUri;
-      rv = NS_NewURI(getter_AddRefs(srcUri), mBehavior.mSoundFile, encoding, baseUri);
+      rv = NS_NewURI(getter_AddRefs(srcUri), mBehavior.mSoundFile, charset, baseUri);
       if (NS_SUCCEEDED(rv)) {
         nsAutoCString src;
         srcUri->GetSpec(src);
         soundUrl = NS_ConvertUTF8toUTF16(src);
       }
     }
   }
 
--- a/dom/presentation/PresentationRequest.cpp
+++ b/dom/presentation/PresentationRequest.cpp
@@ -42,23 +42,21 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEvent
 
 static nsresult
 GetAbsoluteURL(const nsAString& aUrl,
                nsIURI* aBaseUri,
                nsIDocument* aDocument,
                nsAString& aAbsoluteUrl)
 {
   nsCOMPtr<nsIURI> uri;
-  nsresult rv;
-  if (aDocument) {
-    rv = NS_NewURI(getter_AddRefs(uri), aUrl,
-                   aDocument->GetDocumentCharacterSet(), aBaseUri);
-  } else {
-    rv = NS_NewURI(getter_AddRefs(uri), aUrl, nullptr, aBaseUri);
-  }
+  nsresult rv = NS_NewURI(getter_AddRefs(uri),
+                          aUrl,
+                          aDocument ? aDocument->GetDocumentCharacterSet().get()
+                                    : nullptr,
+                          aBaseUri);
 
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   nsAutoCString spec;
   uri->GetSpec(spec);
 
--- a/dom/script/ScriptLoadHandler.cpp
+++ b/dom/script/ScriptLoadHandler.cpp
@@ -223,17 +223,18 @@ ScriptLoadHandler::EnsureDecoder(nsIIncr
   if ((encoding = Encoding::ForLabel(hintCharset))) {
     mDecoder = encoding->NewDecoderWithoutBOMHandling();
     encoding->Name(oCharset);
     return true;
   }
 
   // Get the charset from the charset of the document.
   if (mScriptLoader->mDocument) {
-    encoding = mScriptLoader->mDocument->GetDocumentCharacterSet();
+    encoding =
+      Encoding::ForName(mScriptLoader->mDocument->GetDocumentCharacterSet());
     mDecoder = encoding->NewDecoderWithoutBOMHandling();
     encoding->Name(oCharset);
     return true;
   }
 
   // Curiously, there are various callers that don't pass aDocument. The
   // fallback in the old code was ISO-8859-1, which behaved like
   // windows-1252.
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -2559,17 +2559,17 @@ ScriptLoader::ConvertToUTF16(nsIChannel*
     }
   }
 
   if (!unicodeDecoder && (encoding = Encoding::ForLabel(aHintCharset))) {
     unicodeDecoder = encoding->NewDecoderWithoutBOMHandling();
   }
 
   if (!unicodeDecoder && aDocument) {
-    unicodeDecoder = aDocument->GetDocumentCharacterSet()
+    unicodeDecoder = Encoding::ForName(aDocument->GetDocumentCharacterSet())
                        ->NewDecoderWithoutBOMHandling();
   }
 
   if (!unicodeDecoder) {
     // Curiously, there are various callers that don't pass aDocument. The
     // fallback in the old code was ISO-8859-1, which behaved like
     // windows-1252.
     unicodeDecoder = WINDOWS_1252_ENCODING->NewDecoderWithoutBOMHandling();
--- a/dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
+++ b/dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
@@ -132,17 +132,17 @@ WebBrowserPersistLocalDocument::GetConte
     NS_ENSURE_SUCCESS(rv, rv);
     aContentType = NS_ConvertUTF16toUTF8(utf16Type);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebBrowserPersistLocalDocument::GetCharacterSet(nsACString& aCharSet)
 {
-    GetCharacterSet()->Name(aCharSet);
+    aCharSet = GetCharacterSet();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebBrowserPersistLocalDocument::GetTitle(nsAString& aTitle)
 {
     nsAutoString titleBuffer;
     mDocument->GetTitle(titleBuffer);
@@ -231,17 +231,17 @@ WebBrowserPersistLocalDocument::GetHisto
     // This can fail if, e.g., the document is a Print Preview.
     if (NS_FAILED(rv) || NS_WARN_IF(!curDesc)) {
         return nullptr;
     }
     nsCOMPtr<nsISHEntry> history = do_QueryInterface(curDesc);
     return history.forget();
 }
 
-NotNull<const Encoding*>
+const nsCString&
 WebBrowserPersistLocalDocument::GetCharacterSet() const
 {
     return mDocument->GetDocumentCharacterSet();
 }
 
 uint32_t
 WebBrowserPersistLocalDocument::GetPersistFlags() const
 {
@@ -392,17 +392,17 @@ ResourceReader::OnWalkURI(nsIURI* aURI)
 nsresult
 ResourceReader::OnWalkURI(const nsACString& aURISpec)
 {
     nsresult rv;
     nsCOMPtr<nsIURI> uri;
 
     rv = NS_NewURI(getter_AddRefs(uri),
                    aURISpec,
-                   mParent->GetCharacterSet(),
+                   mParent->GetCharacterSet().get(),
                    mCurrentBaseURI);
     NS_ENSURE_SUCCESS(rv, rv);
     return OnWalkURI(uri);
 }
 
 static nsresult
 ExtractAttribute(nsIDOMNode* aNode,
                  const char* aAttribute,
@@ -547,17 +547,17 @@ ResourceReader::OnWalkDOMNode(nsIDOMNode
         // codebase (which is resolved relative to the base URI).
         nsCOMPtr<nsIURI> oldBase = mCurrentBaseURI;
         nsAutoString codebase;
         rv = nodeAsApplet->GetCodeBase(codebase);
         NS_ENSURE_SUCCESS(rv, rv);
         if (!codebase.IsEmpty()) {
             nsCOMPtr<nsIURI> baseURI;
             rv = NS_NewURI(getter_AddRefs(baseURI), codebase,
-                           mParent->GetCharacterSet(), mCurrentBaseURI);
+                           mParent->GetCharacterSet().get(), mCurrentBaseURI);
             NS_ENSURE_SUCCESS(rv, rv);
             if (baseURI) {
                 mCurrentBaseURI = baseURI;
                 // Must restore this before returning (or ENSURE'ing).
             }
         }
 
         // We only store 'code' locally if there is no 'archive',
@@ -712,17 +712,17 @@ PersistNodeFixup::GetNodeToFixup(nsIDOMN
 }
 
 nsresult
 PersistNodeFixup::FixupURI(nsAString &aURI)
 {
     // get the current location of the file (absolutized)
     nsCOMPtr<nsIURI> uri;
     nsresult rv = NS_NewURI(getter_AddRefs(uri), aURI,
-                            mParent->GetCharacterSet(), mCurrentBaseURI);
+                            mParent->GetCharacterSet().get(), mCurrentBaseURI);
     NS_ENSURE_SUCCESS(rv, rv);
     nsAutoCString spec;
     rv = uri->GetSpec(spec);
     NS_ENSURE_SUCCESS(rv, rv);
 
     const nsCString* replacement = mMap.Get(spec);
     if (!replacement) {
         // Note that most callers ignore this "failure".
@@ -799,17 +799,17 @@ PersistNodeFixup::FixupAnchor(nsIDOMNode
         }
 
         nsCOMPtr<nsIURI> relativeURI;
         relativeURI = IsFlagSet(IWBP::PERSIST_FLAGS_FIXUP_LINKS_TO_DESTINATION)
                       ? mTargetBaseURI : mCurrentBaseURI;
         // Make a new URI to replace the current one
         nsCOMPtr<nsIURI> newURI;
         rv = NS_NewURI(getter_AddRefs(newURI), oldCValue,
-                       mParent->GetCharacterSet(), relativeURI);
+                       mParent->GetCharacterSet().get(), relativeURI);
         if (NS_SUCCEEDED(rv) && newURI) {
             newURI->SetUserPass(EmptyCString());
             nsAutoCString uriSpec;
             rv = newURI->GetSpec(uriSpec);
             NS_ENSURE_SUCCESS(rv, rv);
             attr->SetValue(NS_ConvertUTF8toUTF16(uriSpec));
         }
     }
@@ -1125,17 +1125,17 @@ PersistNodeFixup::FixupNode(nsIDOMNode *
             // For an applet, relative URIs are resolved relative to the
             // codebase (which is resolved relative to the base URI).
             nsCOMPtr<nsIURI> oldBase = mCurrentBaseURI;
             nsAutoString codebase;
             nodeAsApplet->GetCodeBase(codebase);
             if (!codebase.IsEmpty()) {
                 nsCOMPtr<nsIURI> baseURI;
                 NS_NewURI(getter_AddRefs(baseURI), codebase,
-                          mParent->GetCharacterSet(), mCurrentBaseURI);
+                          mParent->GetCharacterSet().get(), mCurrentBaseURI);
                 if (baseURI) {
                     mCurrentBaseURI = baseURI;
                 }
             }
             // Unset the codebase too, since we'll correctly relativize the
             // code and archive paths.
             IgnoredErrorResult ignored;
             static_cast<dom::HTMLSharedObjectElement*>(newApplet.get())->
--- a/dom/webbrowserpersist/WebBrowserPersistLocalDocument.h
+++ b/dom/webbrowserpersist/WebBrowserPersistLocalDocument.h
@@ -19,17 +19,17 @@ class nsISHEntry;
 namespace mozilla {
 
 class WebBrowserPersistLocalDocument final
     : public nsIWebBrowserPersistDocument
 {
 public:
     explicit WebBrowserPersistLocalDocument(nsIDocument* aDocument);
 
-    NotNull<const Encoding*> GetCharacterSet() const;
+    const nsCString& GetCharacterSet() const;
     uint32_t GetPersistFlags() const;
     already_AddRefed<nsIURI> GetBaseURI() const;
 
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     NS_DECL_NSIWEBBROWSERPERSISTDOCUMENT
 
     NS_DECL_CYCLE_COLLECTION_CLASS(WebBrowserPersistLocalDocument)
 
--- a/dom/xbl/nsXBLPrototypeBinding.cpp
+++ b/dom/xbl/nsXBLPrototypeBinding.cpp
@@ -1627,17 +1627,17 @@ nsXBLPrototypeBinding::ResolveBaseBindin
     }
   }
 
   if (hasDisplay || nameSpace.IsEmpty()) {
     mBinding->UnsetAttr(kNameSpaceID_None, nsGkAtoms::extends, false);
     mBinding->UnsetAttr(kNameSpaceID_None, nsGkAtoms::display, false);
 
     return NS_NewURI(getter_AddRefs(mBaseBindingURI), value,
-                     doc->GetDocumentCharacterSet(),
+                     doc->GetDocumentCharacterSet().get(),
                      doc->GetDocBaseURI());
   }
 
   return NS_OK;
 }
 
 void
 nsXBLPrototypeBinding::EnsureResources()
--- a/dom/xbl/nsXBLResourceLoader.cpp
+++ b/dom/xbl/nsXBLResourceLoader.cpp
@@ -108,17 +108,17 @@ nsXBLResourceLoader::LoadResources(nsICo
 
   nsCOMPtr<nsIURI> url;
 
   for (nsXBLResource* curr = mResourceList; curr; curr = curr->mNext) {
     if (curr->mSrc.IsEmpty())
       continue;
 
     if (NS_FAILED(NS_NewURI(getter_AddRefs(url), curr->mSrc,
-                            doc->GetDocumentCharacterSet(), docURL)))
+                            doc->GetDocumentCharacterSet().get(), docURL)))
       continue;
 
     if (curr->mType == nsGkAtoms::image) {
       // Now kick off the image load...
       // Passing nullptr for pretty much everything -- cause we don't care!
       // XXX: initialDocumentURI is nullptr!
       RefPtr<imgRequestProxy> req;
       nsContentUtils::LoadImage(url, doc, doc, docPrincipal, docURL,
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -173,17 +173,16 @@ static void AddLoadFlags(nsIRequest *req
 //
 /////////////////////////////////////////////
 
 bool
 XMLHttpRequestMainThread::sDontWarnAboutSyncXHR = false;
 
 XMLHttpRequestMainThread::XMLHttpRequestMainThread()
   : mResponseBodyDecodedPos(0),
-    mResponseCharset(nullptr),
     mResponseType(XMLHttpRequestResponseType::_empty),
     mRequestObserver(nullptr),
     mState(State::unsent),
     mFlagSynchronous(false), mFlagAborted(false), mFlagParseBody(false),
     mFlagSyncLooping(false), mFlagBackgroundRequest(false),
     mFlagHadUploadListenersOnSend(false), mFlagACwithCredentials(false),
     mFlagTimedOut(false), mFlagDeleted(false), mFlagSend(false),
     mUploadTransferred(0), mUploadTotal(0), mUploadComplete(true),
@@ -488,17 +487,17 @@ XMLHttpRequestMainThread::GetResponseXML
 
 /*
  * This piece copied from XMLDocument, we try to get the charset
  * from HTTP headers.
  */
 nsresult
 XMLHttpRequestMainThread::DetectCharset()
 {
-  mResponseCharset = nullptr;
+  mResponseCharset.Truncate();
   mDecoder = nullptr;
 
   if (mResponseType != XMLHttpRequestResponseType::_empty &&
       mResponseType != XMLHttpRequestResponseType::Text &&
       mResponseType != XMLHttpRequestResponseType::Json &&
       mResponseType != XMLHttpRequestResponseType::Moz_chunked_text) {
     return NS_OK;
   }
@@ -515,17 +514,17 @@ XMLHttpRequestMainThread::DetectCharset(
 
   if (mResponseType == XMLHttpRequestResponseType::Json &&
       encoding != UTF_8_ENCODING) {
     // The XHR spec says only UTF-8 is supported for responseType == "json"
     LogMessage("JSONCharsetWarning", GetOwner());
     encoding = UTF_8_ENCODING;
   }
 
-  mResponseCharset = encoding;
+  encoding->Name(mResponseCharset);
   mDecoder = encoding->NewDecoderWithBOMRemoval();
 
   return NS_OK;
 }
 
 nsresult
 XMLHttpRequestMainThread::AppendToResponseText(const char * aSrcBuffer,
                                                uint32_t aSrcBufferLen)
@@ -2429,17 +2428,17 @@ XMLHttpRequestMainThread::OnBodyParseEnd
 
 void
 XMLHttpRequestMainThread::MatchCharsetAndDecoderToResponseDocument()
 {
   if (mResponseXML && mResponseCharset != mResponseXML->GetDocumentCharacterSet()) {
     mResponseCharset = mResponseXML->GetDocumentCharacterSet();
     TruncateResponseText();
     mResponseBodyDecodedPos = 0;
-    mDecoder = mResponseCharset->NewDecoderWithBOMRemoval();
+    mDecoder = Encoding::ForName(mResponseCharset)->NewDecoderWithBOMRemoval();
   }
 }
 
 void
 XMLHttpRequestMainThread::ChangeStateToDone()
 {
   StopProgressEventTimer();
 
--- a/dom/xhr/XMLHttpRequestMainThread.h
+++ b/dom/xhr/XMLHttpRequestMainThread.h
@@ -703,17 +703,17 @@ protected:
   // Decoder used for decoding into mResponseText
   // Only used for DEFAULT, TEXT and JSON responseTypes.
   // In cases where we've only received half a surrogate, the decoder itself
   // carries the state to remember this. Next time we receive more data we
   // simply feed the new data into the decoder which will handle the second
   // part of the surrogate.
   mozilla::UniquePtr<mozilla::Decoder> mDecoder;
 
-  const Encoding* mResponseCharset;
+  nsCString mResponseCharset;
 
   void MatchCharsetAndDecoderToResponseDocument();
 
   XMLHttpRequestResponseType mResponseType;
 
   // It is either a cached blob-response from the last call to GetResponse,
   // but is also explicitly set in OnStopRequest.
   RefPtr<Blob> mResponseBlob;
--- a/dom/xml/XMLDocument.cpp
+++ b/dom/xml/XMLDocument.cpp
@@ -146,17 +146,17 @@ NS_NewDOMDocument(nsIDOMDocument** aInst
   if (nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aEventObject)) {
     d->SetScriptHandlingObject(sgo);
   } else if (aEventObject){
     d->SetScopeObject(aEventObject);
   }
 
   // XMLDocuments and documents "created in memory" get to be UTF-8 by default,
   // unlike the legacy HTML mess
-  doc->SetDocumentCharacterSet(UTF_8_ENCODING);
+  doc->SetDocumentCharacterSet(NS_LITERAL_CSTRING("UTF-8"));
 
   if (aDoctype) {
     nsCOMPtr<nsINode> doctypeAsNode = do_QueryInterface(aDoctype);
     ErrorResult result;
     d->AppendChild(*doctypeAsNode, result);
     if (NS_WARN_IF(result.Failed())) {
       return result.StealNSResult();
     }
@@ -317,17 +317,17 @@ XMLDocument::Load(const nsAString& aUrl,
     docForWarning->WarnOnceAbout(nsIDocument::eUseOfDOM3LoadMethod);
   }
 
   nsIURI *baseURI = mDocumentURI;
   nsAutoCString charset;
 
   if (callingDoc) {
     baseURI = callingDoc->GetDocBaseURI();
-    callingDoc->GetDocumentCharacterSet()->Name(charset);
+    charset = callingDoc->GetDocumentCharacterSet();
   }
 
   // Create a new URI
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_NewURI(getter_AddRefs(uri), aUrl, charset.get(), baseURI);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return false;
@@ -525,18 +525,18 @@ XMLDocument::StartDocumentLoad(const cha
 
   if (nsCRT::strcmp("loadAsInteractiveData", aCommand) == 0) {
     mLoadedAsInteractiveData = true;
     aCommand = kLoadAsData; // XBL, for example, needs scripts and styles
   }
 
 
   int32_t charsetSource = kCharsetFromDocTypeDefault;
-  NotNull<const Encoding*> encoding = UTF_8_ENCODING;
-  TryChannelCharset(aChannel, charsetSource, encoding, nullptr);
+  nsAutoCString charset(NS_LITERAL_CSTRING("UTF-8"));
+  TryChannelCharset(aChannel, charsetSource, charset, nullptr);
 
   nsCOMPtr<nsIURI> aUrl;
   rv = aChannel->GetURI(getter_AddRefs(aUrl));
   if (NS_FAILED(rv)) return rv;
 
   static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
 
   mParser = do_CreateInstance(kCParserCID, &rv);
@@ -560,18 +560,18 @@ XMLDocument::StartDocumentLoad(const cha
 
   // Set the parser as the stream listener for the document loader...
   rv = CallQueryInterface(mParser, aDocListener);
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_ASSERTION(mChannel, "How can we not have a channel here?");
   mChannelIsPending = true;
 
-  SetDocumentCharacterSet(encoding);
-  mParser->SetDocumentCharset(encoding, charsetSource);
+  SetDocumentCharacterSet(charset);
+  mParser->SetDocumentCharset(charset, charsetSource);
   mParser->SetCommand(aCommand);
   mParser->SetContentSink(sink);
   mParser->Parse(aUrl, nullptr, (void *)this);
 
   return NS_OK;
 }
 
 void
--- a/dom/xml/XMLStylesheetProcessingInstruction.cpp
+++ b/dom/xml/XMLStylesheetProcessingInstruction.cpp
@@ -109,24 +109,25 @@ XMLStylesheetProcessingInstruction::GetS
   *aIsInline = false;
 
   nsAutoString href;
   if (!GetAttrValue(nsGkAtoms::href, href)) {
     return nullptr;
   }
 
   nsIURI *baseURL;
+  nsAutoCString charset;
   nsIDocument *document = OwnerDoc();
   baseURL = mOverriddenBaseURI ?
             mOverriddenBaseURI.get() :
             document->GetDocBaseURI();
-  auto encoding = document->GetDocumentCharacterSet();
+  charset = document->GetDocumentCharacterSet();
 
   nsCOMPtr<nsIURI> aURI;
-  NS_NewURI(getter_AddRefs(aURI), href, encoding, baseURL);
+  NS_NewURI(getter_AddRefs(aURI), href, charset.get(), baseURL);
   return aURI.forget();
 }
 
 void
 XMLStylesheetProcessingInstruction::GetStyleSheetInfo(nsAString& aTitle,
                                                       nsAString& aType,
                                                       nsAString& aMedia,
                                                       bool* aIsScoped,
--- a/dom/xml/nsXMLContentSink.cpp
+++ b/dom/xml/nsXMLContentSink.cpp
@@ -726,22 +726,24 @@ nsXMLContentSink::ProcessStyleLink(nsICo
                                        aTitle, aType, aMedia);
 
   // nsContentSink::ProcessStyleLink handles the bookkeeping here wrt
   // pending sheets.
 
   return rv;
 }
 
-void
-nsXMLContentSink::SetDocumentCharset(NotNull<const Encoding*> aEncoding)
+NS_IMETHODIMP
+nsXMLContentSink::SetDocumentCharset(nsACString& aCharset)
 {
   if (mDocument) {
-    mDocument->SetDocumentCharacterSet(aEncoding);
+    mDocument->SetDocumentCharacterSet(aCharset);
   }
+
+  return NS_OK;
 }
 
 nsISupports *
 nsXMLContentSink::GetTarget()
 {
   return mDocument;
 }
 
--- a/dom/xml/nsXMLContentSink.h
+++ b/dom/xml/nsXMLContentSink.h
@@ -65,17 +65,17 @@ public:
   // nsIContentSink
   NS_IMETHOD WillParse(void) override;
   NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override;
   NS_IMETHOD DidBuildModel(bool aTerminated) override;
   NS_IMETHOD WillInterrupt(void) override;
   NS_IMETHOD WillResume(void) override;
   NS_IMETHOD SetParser(nsParserBase* aParser) override;
   virtual void FlushPendingNotifications(mozilla::FlushType aType) override;
-  virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override;
+  NS_IMETHOD SetDocumentCharset(nsACString& aCharset) override;
   virtual nsISupports *GetTarget() override;
   virtual bool IsScriptExecuting() override;
   virtual void ContinueInterruptedParsingAsync() override;
 
   // nsITransformObserver
   NS_IMETHOD OnDocumentCreated(nsIDocument *aResultDocument) override;
   NS_IMETHOD OnTransformDone(nsresult aResult, nsIDocument *aResultDocument) override;
 
--- a/dom/xml/nsXMLFragmentContentSink.cpp
+++ b/dom/xml/nsXMLFragmentContentSink.cpp
@@ -57,17 +57,17 @@ public:
   NS_IMETHOD ReportError(const char16_t* aErrorText,
                          const char16_t* aSourceText,
                          nsIScriptError* aError,
                          bool* aRetval) override;
 
   // nsIContentSink
   NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override;
   NS_IMETHOD DidBuildModel(bool aTerminated) override;
-  virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override;
+  NS_IMETHOD SetDocumentCharset(nsACString& aCharset) override;
   virtual nsISupports* GetTarget() override;
   NS_IMETHOD DidProcessATokenImpl();
 
   // nsIXMLContentSink
 
   // nsIFragmentContentSink
   NS_IMETHOD FinishFragmentParsing(nsIDOMDocumentFragment** aFragment) override;
   NS_IMETHOD SetTargetDocument(nsIDocument* aDocument) override;
@@ -168,21 +168,21 @@ nsXMLFragmentContentSink::DidBuildModel(
 {
   // Drop our reference to the parser to get rid of a circular
   // reference.
   mParser = nullptr;
 
   return NS_OK;
 }
 
-void 
-nsXMLFragmentContentSink::SetDocumentCharset(
-  NotNull<const Encoding*> aEncoding)
+NS_IMETHODIMP 
+nsXMLFragmentContentSink::SetDocumentCharset(nsACString& aCharset)
 {
   NS_NOTREACHED("fragments shouldn't set charset");
+  return NS_OK;
 }
 
 nsISupports *
 nsXMLFragmentContentSink::GetTarget()
 {
   return mTargetDocument;
 }
 
--- a/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
+++ b/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
@@ -79,18 +79,17 @@ public:
 
     // nsIContentSink
     NS_IMETHOD WillParse(void) override { return NS_OK; }
     NS_IMETHOD DidBuildModel(bool aTerminated) override;
     NS_IMETHOD WillInterrupt(void) override { return NS_OK; }
     NS_IMETHOD WillResume(void) override { return NS_OK; }
     NS_IMETHOD SetParser(nsParserBase* aParser) override { return NS_OK; }
     virtual void FlushPendingNotifications(mozilla::FlushType aType) override { }
-    virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding)
-      override { }
+    NS_IMETHOD SetDocumentCharset(nsACString& aCharset) override { return NS_OK; }
     virtual nsISupports *GetTarget() override { return nullptr; }
 
 private:
     RefPtr<txStylesheetCompiler> mCompiler;
     nsCOMPtr<nsIStreamListener>    mListener;
     nsCOMPtr<nsIParser>            mParser;
     bool mCheckedForXML;
 
@@ -265,17 +264,19 @@ txStylesheetSink::OnStartRequest(nsIRequ
             charsetSource = kCharsetFromChannel;
         }
     }
 
     if (!encoding) {
         encoding = UTF_8_ENCODING;
     }
 
-    mParser->SetDocumentCharset(WrapNotNull(encoding), charsetSource);
+    nsAutoCString charset;
+    encoding->Name(charset);
+    mParser->SetDocumentCharset(charset, charsetSource);
 
     nsAutoCString contentType;
     channel->GetContentType(contentType);
 
     // Time to sniff! Note: this should go away once file channels do
     // sniffing themselves.
     nsCOMPtr<nsIURI> uri;
     channel->GetURI(getter_AddRefs(uri));
--- a/dom/xslt/xslt/txMozillaTextOutput.cpp
+++ b/dom/xslt/xslt/txMozillaTextOutput.cpp
@@ -158,17 +158,19 @@ txMozillaTextOutput::createResultDocumen
     // correct principal.
     mDocument->SetScriptHandlingObject(sgo);
 
     // Set the charset
     if (!mOutputFormat.mEncoding.IsEmpty()) {
         const Encoding* encoding = Encoding::ForLabel(mOutputFormat.mEncoding);
         if (encoding) {
             mDocument->SetDocumentCharacterSetSource(kCharsetFromOtherComponent);
-            mDocument->SetDocumentCharacterSet(WrapNotNull(encoding));
+            nsAutoCString canonicalCharset;
+            encoding->Name(canonicalCharset);
+            mDocument->SetDocumentCharacterSet(canonicalCharset);
         }
     }
 
     // Notify the contentsink that the document is created
     nsCOMPtr<nsITransformObserver> observer = do_QueryReferent(mObserver);
     if (observer) {
         rv = observer->OnDocumentCreated(mDocument);
         NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/xslt/xslt/txMozillaXMLOutput.cpp
+++ b/dom/xslt/xslt/txMozillaXMLOutput.cpp
@@ -818,17 +818,19 @@ txMozillaXMLOutput::createResultDocument
     // source, so that we have the right principal.
     mDocument->SetScriptHandlingObject(sgo);
 
     // Set the charset
     if (!mOutputFormat.mEncoding.IsEmpty()) {
         const Encoding* encoding = Encoding::ForLabel(mOutputFormat.mEncoding);
         if (encoding) {
             mDocument->SetDocumentCharacterSetSource(kCharsetFromOtherComponent);
-            mDocument->SetDocumentCharacterSet(WrapNotNull(encoding));
+            nsAutoCString canonicalCharset;
+            encoding->Name(canonicalCharset);
+            mDocument->SetDocumentCharacterSet(canonicalCharset);
         }
     }
 
     // Set the mime-type
     if (!mOutputFormat.mMediaType.IsEmpty()) {
         mDocument->SetContentType(mOutputFormat.mMediaType);
     }
     else if (mOutputFormat.mMethod == eHTMLOutput) {
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -208,17 +208,17 @@ XULDocument::XULDocument(void)
       mOffThreadCompileStringLength(0),
       mResolutionPhase(nsForwardReference::eStart),
       mBroadcasterMap(nullptr),
       mInitialLayoutComplete(false),
       mHandlingDelayedAttrChange(false),
       mHandlingDelayedBroadcasters(false)
 {
     // Override the default in nsDocument
-    mCharacterSet = UTF_8_ENCODING;
+    mCharacterSet.AssignLiteral("UTF-8");
 
     mDefaultElementType = kNameSpaceID_XUL;
     mType = eXUL;
 
     mDelayFrameLoaderInitialization = true;
 
     mAllowXULXBL = eTriTrue;
 }
@@ -2016,17 +2016,17 @@ XULDocument::PrepareToLoadPrototype(nsIU
 
     nsCOMPtr<nsIParser> parser = do_CreateInstance(kParserCID, &rv);
     NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create parser");
     if (NS_FAILED(rv)) return rv;
 
     parser->SetCommand(nsCRT::strcmp(aCommand, "view-source") ? eViewNormal :
                        eViewSource);
 
-    parser->SetDocumentCharset(UTF_8_ENCODING,
+    parser->SetDocumentCharset(NS_LITERAL_CSTRING("UTF-8"),
                                kCharsetFromDocTypeDefault);
     parser->SetContentSink(sink); // grabs a reference to the parser
 
     parser.forget(aResult);
     return NS_OK;
 }
 
 
--- a/dom/xul/nsXULContentSink.cpp
+++ b/dom/xul/nsXULContentSink.cpp
@@ -251,23 +251,25 @@ XULContentSinkImpl::WillResume(void)
 
 NS_IMETHODIMP
 XULContentSinkImpl::SetParser(nsParserBase* aParser)
 {
     mParser = aParser;
     return NS_OK;
 }
 
-void
-XULContentSinkImpl::SetDocumentCharset(NotNull<const Encoding*> aEncoding)
+NS_IMETHODIMP
+XULContentSinkImpl::SetDocumentCharset(nsACString& aCharset)
 {
     nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
     if (doc) {
-        doc->SetDocumentCharacterSet(aEncoding);
+        doc->SetDocumentCharacterSet(aCharset);
     }
+
+    return NS_OK;
 }
 
 nsISupports *
 XULContentSinkImpl::GetTarget()
 {
     nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
     return doc;
 }
--- a/dom/xul/nsXULContentSink.h
+++ b/dom/xul/nsXULContentSink.h
@@ -36,17 +36,17 @@ public:
     // nsIContentSink
     NS_IMETHOD WillParse(void) override { return NS_OK; }
     NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override;
     NS_IMETHOD DidBuildModel(bool aTerminated) override;
     NS_IMETHOD WillInterrupt(void) override;
     NS_IMETHOD WillResume(void) override;
     NS_IMETHOD SetParser(nsParserBase* aParser) override;
     virtual void FlushPendingNotifications(mozilla::FlushType aType) override { }
-    virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override;
+    NS_IMETHOD SetDocumentCharset(nsACString& aCharset) override;
     virtual nsISupports *GetTarget() override;
 
     /**
      * Initialize the content sink, giving it an nsIDocument object
      * with which to communicate with the outside world, and an
      * nsXULPrototypeDocument to build.
      */
     nsresult Init(nsIDocument* aDocument, nsXULPrototypeDocument* aPrototype);
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "mozilla/EditorBase.h"
 
 #include "mozilla/DebugOnly.h"          // for DebugOnly
-#include "mozilla/Encoding.h"           // for Encoding
 
 #include <stdio.h>                      // for nullptr, stdout
 #include <string.h>                     // for strcmp
 
 #include "ChangeAttributeTransaction.h" // for ChangeAttributeTransaction
 #include "CompositionTransaction.h"     // for CompositionTransaction
 #include "CreateElementTransaction.h"   // for CreateElementTransaction
 #include "DeleteNodeTransaction.h"      // for DeleteNodeTransaction
@@ -1176,34 +1175,28 @@ EditorBase::GetDocumentModified(bool* ou
 
 NS_IMETHODIMP
 EditorBase::GetDocumentCharacterSet(nsACString& characterSet)
 {
   nsCOMPtr<nsIDocument> document = GetDocument();
   if (NS_WARN_IF(!document)) {
     return NS_ERROR_UNEXPECTED;
   }
-  document->GetDocumentCharacterSet()->Name(characterSet);
+  characterSet = document->GetDocumentCharacterSet();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 EditorBase::SetDocumentCharacterSet(const nsACString& characterSet)
 {
   nsCOMPtr<nsIDocument> document = GetDocument();
   if (NS_WARN_IF(!document)) {
     return NS_ERROR_UNEXPECTED;
   }
-  // This method is scriptable, so add-ons could pass in something other
-  // than a canonical name.
-  auto encoding = Encoding::ForLabelNoReplacement(characterSet);
-  if (!encoding) {
-    return NS_ERROR_INVALID_ARG;
-  }
-  document->SetDocumentCharacterSet(WrapNotNull(encoding));
+  document->SetDocumentCharacterSet(characterSet);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 EditorBase::Cut()
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
--- a/intl/locale/nsLanguageAtomService.cpp
+++ b/intl/locale/nsLanguageAtomService.cpp
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsLanguageAtomService.h"
 #include "nsUConvPropertySearch.h"
 #include "nsUnicharUtils.h"
 #include "nsIAtom.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/ClearOnShutdown.h"
-#include "mozilla/Encoding.h"
 #include "mozilla/intl/OSPreferences.h"
 #include "mozilla/ServoBindings.h"
 
 using namespace mozilla;
 using mozilla::intl::OSPreferences;
 
 static constexpr nsUConvProp encodingsGroups[] = {
 #include "encodingsgroups.properties.h"
@@ -42,23 +41,21 @@ nsLanguageAtomService::LookupLanguage(co
   nsAutoCString lowered(aLanguage);
   ToLowerCase(lowered);
 
   nsCOMPtr<nsIAtom> lang = NS_Atomize(lowered);
   return GetLanguageGroup(lang);
 }
 
 already_AddRefed<nsIAtom>
-nsLanguageAtomService::LookupCharSet(NotNull<const Encoding*> aEncoding)
+nsLanguageAtomService::LookupCharSet(const nsACString& aCharSet)
 {
-  nsAutoCString charset;
-  aEncoding->Name(charset);
   nsAutoCString group;
   if (NS_FAILED(nsUConvPropertySearch::SearchPropertyValue(
-      encodingsGroups, ArrayLength(encodingsGroups), charset, group))) {
+      encodingsGroups, ArrayLength(encodingsGroups), aCharSet, group))) {
     return RefPtr<nsIAtom>(nsGkAtoms::Unicode).forget();
   }
   return NS_Atomize(group);
 }
 
 nsIAtom*
 nsLanguageAtomService::GetLocaleLanguage()
 {
--- a/intl/locale/nsLanguageAtomService.h
+++ b/intl/locale/nsLanguageAtomService.h
@@ -6,34 +6,27 @@
 /*
  * The nsILanguageAtomService provides a mapping from languages or charsets
  * to language groups, and access to the system locale language.
  */
 
 #ifndef nsLanguageAtomService_h_
 #define nsLanguageAtomService_h_
 
-#include "mozilla/NotNull.h"
 #include "nsCOMPtr.h"
 #include "nsIAtom.h"
 #include "nsInterfaceHashtable.h"
 
-namespace mozilla {
-class Encoding;
-}
-
-class nsLanguageAtomService final
+class nsLanguageAtomService
 {
-  using Encoding = mozilla::Encoding;
-  template <typename T> using NotNull = mozilla::NotNull<T>;
 public:
   static nsLanguageAtomService* GetService();
 
   nsIAtom* LookupLanguage(const nsACString &aLanguage);
-  already_AddRefed<nsIAtom> LookupCharSet(NotNull<const Encoding*> aCharSet);
+  already_AddRefed<nsIAtom> LookupCharSet(const nsACString& aCharSet);
   nsIAtom* GetLocaleLanguage();
 
   // Returns the language group that the specified language is a part of.
   //
   // aNeedsToCache is used for two things.  If null, it indicates that
   // the nsLanguageAtomService is safe to cache the result of the
   // language group lookup, either because we're on the main thread,
   // or because we're on a style worker thread but the font lock has
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2,17 +2,16 @@
 /* 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/. */
 
 /* a presentation of a document, part 1 */
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/DebugOnly.h"
-#include "mozilla/Encoding.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStateManager.h"
 
 #include "base/basictypes.h"
 
 #include "nsCOMPtr.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
@@ -116,32 +115,32 @@ public:
 };
 
 namespace {
 
 class CharSetChangingRunnable : public Runnable
 {
 public:
   CharSetChangingRunnable(nsPresContext* aPresContext,
-                          NotNull<const Encoding*> aCharSet)
+                          const nsCString& aCharSet)
     : Runnable("CharSetChangingRunnable"),
       mPresContext(aPresContext),
       mCharSet(aCharSet)
   {
   }
 
   NS_IMETHOD Run() override
   {
     mPresContext->DoChangeCharSet(mCharSet);
     return NS_OK;
   }
 
 private:
   RefPtr<nsPresContext> mPresContext;
-  NotNull<const Encoding*> mCharSet;
+  nsCString mCharSet;
 };
 
 } // namespace
 
 nscolor
 nsPresContext::MakeColorPref(const nsString& aColor)
 {
   nsCSSParser parser;
@@ -192,19 +191,25 @@ nsPresContext::PrefChangedUpdateTimerCal
 {
   nsPresContext*  presContext = (nsPresContext*)aClosure;
   NS_ASSERTION(presContext != nullptr, "bad instance data");
   if (presContext)
     presContext->UpdateAfterPreferencesChanged();
 }
 
 static bool
-IsVisualCharset(NotNull<const Encoding*> aCharset)
+IsVisualCharset(const nsCString& aCharset)
 {
-  return aCharset == ISO_8859_8_ENCODING;
+  if (aCharset.LowerCaseEqualsLiteral("ibm862")             // Hebrew
+      || aCharset.LowerCaseEqualsLiteral("iso-8859-8") ) {  // Hebrew
+    return true; // visual text type
+  }
+  else {
+    return false; // logical text type
+  }
 }
 
 nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType)
   : mType(aType),
     mShell(nullptr),
     mDocument(aDocument),
     mMedium(aType == eContext_Galley ? nsGkAtoms::screen : nsGkAtoms::print),
     mMediaEmulated(mMedium),
@@ -1060,25 +1065,25 @@ nsPresContext::DetachShell()
     thisRoot->CancelApplyPluginGeometryTimer();
 
     // The did-paint timer also depends on a non-null pres shell.
     thisRoot->CancelAllDidPaintTimers();
   }
 }
 
 void
-nsPresContext::DoChangeCharSet(NotNull<const Encoding*> aCharSet)
+nsPresContext::DoChangeCharSet(const nsCString& aCharSet)
 {
   UpdateCharSet(aCharSet);
   mDeviceContext->FlushFontCache();
   RebuildAllStyleData(NS_STYLE_HINT_REFLOW, nsRestyleHint(0));
 }
 
 void
-nsPresContext::UpdateCharSet(NotNull<const Encoding*> aCharSet)
+nsPresContext::UpdateCharSet(const nsCString& aCharSet)
 {
   mLanguage = mLangService->LookupCharSet(aCharSet);
   // this will be a language group (or script) code rather than a true language code
 
   // bug 39570: moved from nsLanguageAtomService::LookupCharSet()
   if (mLanguage == nsGkAtoms::Unicode) {
     mLanguage = mLangService->GetLocaleLanguage();
   }
@@ -1102,19 +1107,18 @@ nsPresContext::UpdateCharSet(NotNull<con
 }
 
 NS_IMETHODIMP
 nsPresContext::Observe(nsISupports* aSubject,
                         const char* aTopic,
                         const char16_t* aData)
 {
   if (!nsCRT::strcmp(aTopic, "charset")) {
-    auto encoding = Encoding::ForName(NS_LossyConvertUTF16toASCII(aData));
     RefPtr<CharSetChangingRunnable> runnable =
-      new CharSetChangingRunnable(this, encoding);
+      new CharSetChangingRunnable(this, NS_LossyConvertUTF16toASCII(aData));
     return Document()->Dispatch("CharSetChangingRunnable",
                                 TaskCategory::Other,
                                 runnable.forget());
   }
 
   NS_WARNING("unrecognized topic in nsPresContext::Observe");
   return NS_ERROR_FAILURE;
 }
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* a presentation of a document, part 1 */
 
 #ifndef nsPresContext_h___
 #define nsPresContext_h___
 
 #include "mozilla/Attributes.h"
-#include "mozilla/NotNull.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/WeakPtr.h"
 #include "nsColor.h"
 #include "nsCoord.h"
 #include "nsCOMPtr.h"
 #include "nsIPresShell.h"
 #include "nsRect.h"
 #include "nsFont.h"
@@ -67,17 +66,16 @@ class nsTransitionManager;
 class nsAnimationManager;
 class nsRefreshDriver;
 class nsIWidget;
 class nsDeviceContext;
 class gfxMissingFontRecorder;
 
 namespace mozilla {
 class EffectCompositor;
-class Encoding;
 class EventStateManager;
 class CounterStyleManager;
 class RestyleManager;
 namespace layers {
 class ContainerLayer;
 class LayerManager;
 } // namespace layers
 namespace dom {
@@ -122,18 +120,16 @@ enum nsLayoutPhase {
 class nsRootPresContext;
 
 // An interface for presentation contexts. Presentation contexts are
 // objects that provide an outer context for a presentation shell.
 
 class nsPresContext : public nsIObserver,
                       public mozilla::SupportsWeakPtr<nsPresContext> {
 public:
-  using Encoding = mozilla::Encoding;
-  template <typename T> using NotNull = mozilla::NotNull<T>;
   typedef mozilla::LangGroupFontPrefs LangGroupFontPrefs;
   typedef mozilla::ScrollbarStyles ScrollbarStyles;
   typedef mozilla::StaticPresData StaticPresData;
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_NSIOBSERVER
   NS_DECL_CYCLE_COLLECTION_CLASS(nsPresContext)
   MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsPresContext)
@@ -1227,22 +1223,22 @@ protected:
    * langugage group.
    */
   const LangGroupFontPrefs* GetFontPrefsForLang(nsIAtom *aLanguage, bool* aNeedsToCache = nullptr) const
   {
     nsIAtom* lang = aLanguage ? aLanguage : mLanguage.get();
     return StaticPresData::Get()->GetFontPrefsForLangHelper(lang, &mLangGroupFontPrefs, aNeedsToCache);
   }
 
-  void UpdateCharSet(NotNull<const Encoding*> aCharSet);
+  void UpdateCharSet(const nsCString& aCharSet);
 
   static bool NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* aData);
 
 public:
-  void DoChangeCharSet(NotNull<const Encoding*> aCharSet);
+  void DoChangeCharSet(const nsCString& aCharSet);
 
   /**
    * Checks for MozAfterPaint listeners on the document
    */
   bool MayHavePaintEventListener();
 
   /**
    * Checks for MozAfterPaint listeners on the document and
--- a/layout/build/nsContentDLF.cpp
+++ b/layout/build/nsContentDLF.cpp
@@ -1,18 +1,15 @@
 /* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 sw=2 et tw=78: */
 /* 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 "nsCOMPtr.h"
 #include "nsContentDLF.h"
-
-#include "mozilla/Encoding.h"
-
-#include "nsCOMPtr.h"
 #include "nsDocShell.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsIComponentManager.h"
 #include "nsIComponentRegistrar.h"
 #include "nsIContentViewer.h"
 #include "nsICategoryManager.h"
 #include "nsIDocumentLoaderFactory.h"
@@ -325,17 +322,17 @@ nsContentDLF::CreateBlankDocument(nsILoa
         }
       }
     }
   }
 
   // add a nice bow
   if (NS_SUCCEEDED(rv)) {
     blankDoc->SetDocumentCharacterSetSource(kCharsetFromDocTypeDefault);
-    blankDoc->SetDocumentCharacterSet(UTF_8_ENCODING);
+    blankDoc->SetDocumentCharacterSet(NS_LITERAL_CSTRING("UTF-8"));
     
     blankDoc.forget(aDocument);
   }
   return rv;
 }
 
 
 nsresult
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -6,17 +6,16 @@
 /* rendering object for replaced elements with image data */
 
 #include "nsImageFrame.h"
 
 #include "gfx2DGlue.h"
 #include "gfxContext.h"
 #include "gfxUtils.h"
 #include "mozilla/DebugOnly.h"
-#include "mozilla/Encoding.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Helpers.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Unused.h"
 
 #include "nsCOMPtr.h"
@@ -2247,17 +2246,17 @@ nsImageFrame::LoadIcon(const nsAString& 
 }
 
 void
 nsImageFrame::GetDocumentCharacterSet(nsACString& aCharset) const
 {
   if (mContent) {
     NS_ASSERTION(mContent->GetComposedDoc(),
                  "Frame still alive after content removed from document!");
-    mContent->GetComposedDoc()->GetDocumentCharacterSet()->Name(aCharset);
+    aCharset = mContent->GetComposedDoc()->GetDocumentCharacterSet();
   }
 }
 
 void
 nsImageFrame::SpecToURI(const nsAString& aSpec, nsIIOService *aIOService,
                          nsIURI **aURI)
 {
   nsCOMPtr<nsIURI> baseURI;
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -756,18 +756,18 @@ SheetLoadData::OnDetermineCharset(nsIUni
       LOG(("  Setting from parent sheet to: %s",
           PromiseFlatCString(aCharset).get()));
       return NS_OK;
     }
   }
 
   if (mLoader->mDocument) {
     // no useful data on charset.  Try the document charset.
-    auto encoding = mLoader->mDocument->GetDocumentCharacterSet();
-    encoding->Name(aCharset);
+    aCharset = mLoader->mDocument->GetDocumentCharacterSet();
+    MOZ_ASSERT(!aCharset.IsEmpty());
     mCharset.Assign(aCharset);
     LOG(("  Setting from document to: %s", PromiseFlatCString(aCharset).get()));
     return NS_OK;
   }
 
   aCharset.AssignLiteral("UTF-8");
   mCharset = aCharset;
   LOG(("  Setting from default to: %s", PromiseFlatCString(aCharset).get()));
--- a/netwerk/base/nsNetUtil.cpp
+++ b/netwerk/base/nsNetUtil.cpp
@@ -2,23 +2,21 @@
 /* vim:set ts=4 sw=4 sts=4 et cin: */
 /* 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/. */
 
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
-#include "nsNetUtil.h"
-
-#include "mozilla/Encoding.h"
 #include "mozilla/LoadContext.h"
 #include "mozilla/LoadInfo.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/Telemetry.h"
+#include "nsNetUtil.h"
 #include "nsCategoryCache.h"
 #include "nsContentUtils.h"
 #include "nsHashKeys.h"
 #include "nsHttp.h"
 #include "nsIAsyncStreamCopier.h"
 #include "nsIAuthPrompt.h"
 #include "nsIAuthPrompt2.h"
 #include "nsIAuthPromptAdapterFactory.h"
@@ -1534,48 +1532,26 @@ NS_NewURI(nsIURI **result,
     rv = net_EnsureIOService(&ioService, grip);
     if (ioService)
         rv = ioService->NewURI(spec, charset, baseURI, result);
     return rv;
 }
 
 nsresult
 NS_NewURI(nsIURI **result,
-          const nsACString &spec,
-          NotNull<const Encoding*> encoding,
-          nsIURI *baseURI /* = nullptr */,
-          nsIIOService *ioService /* = nullptr */)     // pass in nsIIOService to optimize callers
-{
-    nsAutoCString charset;
-    encoding->Name(charset);
-    return NS_NewURI(result, spec, charset.get(), baseURI, ioService);
-}
-
-nsresult
-NS_NewURI(nsIURI **result,
           const nsAString &spec,
           const char *charset /* = nullptr */,
           nsIURI *baseURI /* = nullptr */,
           nsIIOService *ioService /* = nullptr */)     // pass in nsIIOService to optimize callers
 {
     return NS_NewURI(result, NS_ConvertUTF16toUTF8(spec), charset, baseURI, ioService);
 }
 
 nsresult
 NS_NewURI(nsIURI **result,
-          const nsAString &spec,
-          NotNull<const Encoding*> encoding,
-          nsIURI *baseURI /* = nullptr */,
-          nsIIOService *ioService /* = nullptr */)     // pass in nsIIOService to optimize callers
-{
-    return NS_NewURI(result, NS_ConvertUTF16toUTF8(spec), encoding, baseURI, ioService);
-}
-
-nsresult
-NS_NewURI(nsIURI **result,
           const char *spec,
           nsIURI *baseURI /* = nullptr */,
           nsIIOService *ioService /* = nullptr */)     // pass in nsIIOService to optimize callers
 {
     return NS_NewURI(result, nsDependentCString(spec), nullptr, baseURI, ioService);
 }
 
 nsresult
--- a/netwerk/base/nsNetUtil.h
+++ b/netwerk/base/nsNetUtil.h
@@ -10,17 +10,16 @@
 #include "nsCOMPtr.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsILoadGroup.h"
 #include "nsINetUtil.h"
 #include "nsIRequest.h"
 #include "nsILoadInfo.h"
 #include "nsIIOService.h"
-#include "mozilla/NotNull.h"
 #include "mozilla/Services.h"
 #include "mozilla/Unused.h"
 #include "nsNetCID.h"
 #include "nsReadableUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
 
 class nsIURI;
@@ -47,20 +46,17 @@ class nsIRequestObserver;
 class nsIStreamListener;
 class nsIStreamLoader;
 class nsIStreamLoaderObserver;
 class nsIIncrementalStreamLoader;
 class nsIIncrementalStreamLoaderObserver;
 class nsIUnicharStreamLoader;
 class nsIUnicharStreamLoaderObserver;
 
-namespace mozilla {
-class Encoding;
-class OriginAttributes;
-}
+namespace mozilla { class OriginAttributes; }
 
 template <class> class nsCOMPtr;
 template <typename> struct already_AddRefed;
 
 already_AddRefed<nsIIOService> do_GetIOService(nsresult *error = 0);
 
 already_AddRefed<nsINetUtil> do_GetNetUtil(nsresult *error = 0);
 
@@ -69,34 +65,22 @@ nsresult net_EnsureIOService(nsIIOServic
 
 nsresult NS_NewURI(nsIURI **result,
                    const nsACString &spec,
                    const char *charset = nullptr,
                    nsIURI *baseURI = nullptr,
                    nsIIOService *ioService = nullptr);     // pass in nsIIOService to optimize callers
 
 nsresult NS_NewURI(nsIURI **result,
-                   const nsACString &spec,
-                   mozilla::NotNull<const mozilla::Encoding*> encoding,
-                   nsIURI *baseURI = nullptr,
-                   nsIIOService *ioService = nullptr);     // pass in nsIIOService to optimize callers
-
-nsresult NS_NewURI(nsIURI **result,
                    const nsAString &spec,
                    const char *charset = nullptr,
                    nsIURI *baseURI = nullptr,
                    nsIIOService *ioService = nullptr);     // pass in nsIIOService to optimize callers
 
 nsresult NS_NewURI(nsIURI **result,
-                   const nsAString &spec,
-                   mozilla::NotNull<const mozilla::Encoding*> encoding,
-                   nsIURI *baseURI = nullptr,
-                   nsIIOService *ioService = nullptr);     // pass in nsIIOService to optimize callers
-
-nsresult NS_NewURI(nsIURI **result,
                   const char *spec,
                   nsIURI *baseURI = nullptr,
                   nsIIOService *ioService = nullptr);     // pass in nsIIOService to optimize callers
 
 nsresult NS_NewFileURI(nsIURI **result,
                        nsIFile *spec,
                        nsIIOService *ioService = nullptr);     // pass in nsIIOService to optimize callers
 
--- a/netwerk/streamconv/converters/nsDirIndexParser.cpp
+++ b/netwerk/streamconv/converters/nsDirIndexParser.cpp
@@ -1,26 +1,26 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 /* This parsing code originally lived in xpfe/components/directory/ - bbaetz */
 
-#include "nsDirIndexParser.h"
+#include "mozilla/ArrayUtils.h"
 
-#include "mozilla/ArrayUtils.h"
-#include "mozilla/dom/FallbackEncoding.h"
-#include "mozilla/Encoding.h"
 #include "prprf.h"
+
+#include "nsDirIndexParser.h"
+#include "nsEscape.h"
+#include "nsIInputStream.h"
 #include "nsCRT.h"
-#include "nsEscape.h"
+#include "mozilla/dom/FallbackEncoding.h"
+#include "nsITextToSubURI.h"
 #include "nsIDirIndex.h"
-#include "nsIInputStream.h"
-#include "nsITextToSubURI.h"
 #include "nsServiceManagerUtils.h"
 
 using namespace mozilla;
 
 NS_IMPL_ISUPPORTS(nsDirIndexParser,
                   nsIRequestObserver,
                   nsIStreamListener,
                   nsIDirIndexParser)
@@ -28,18 +28,17 @@ NS_IMPL_ISUPPORTS(nsDirIndexParser,
 nsDirIndexParser::nsDirIndexParser() {
 }
 
 nsresult
 nsDirIndexParser::Init() {
   mLineStart = 0;
   mHasDescription = false;
   mFormat[0] = -1;
-  auto encoding = mozilla::dom::FallbackEncoding::FromLocale();
-  encoding->Name(mEncoding);
+  mozilla::dom::FallbackEncoding::FromLocale(mEncoding);
  
   nsresult rv;
   // XXX not threadsafe
   if (gRefCntParser++ == 0)
     rv = CallGetService(NS_ITEXTTOSUBURI_CONTRACTID, &gTextToSubURI);
   else
     rv = NS_OK;
 
--- a/parser/html/nsHtml5DocumentBuilder.cpp
+++ b/parser/html/nsHtml5DocumentBuilder.cpp
@@ -44,22 +44,21 @@ nsHtml5DocumentBuilder::~nsHtml5Document
 nsresult
 nsHtml5DocumentBuilder::MarkAsBroken(nsresult aReason)
 {
   mBroken = aReason;
   return aReason;
 }
 
 void
-nsHtml5DocumentBuilder::SetDocumentCharsetAndSource(NotNull<const Encoding*> aEncoding,
-                                                    int32_t aCharsetSource)
+nsHtml5DocumentBuilder::SetDocumentCharsetAndSource(nsACString& aCharset, int32_t aCharsetSource)
 {
   if (mDocument) {
     mDocument->SetDocumentCharacterSetSource(aCharsetSource);
-    mDocument->SetDocumentCharacterSet(aEncoding);
+    mDocument->SetDocumentCharacterSet(aCharset);
   }
 }
 
 void
 nsHtml5DocumentBuilder::UpdateStyleSheet(nsIContent* aElement)
 {
   nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(aElement));
   if (!ssle) {
--- a/parser/html/nsHtml5DocumentBuilder.h
+++ b/parser/html/nsHtml5DocumentBuilder.h
@@ -18,18 +18,16 @@ enum eHtml5FlushState {
   eNotFlushing = 0,  // not flushing
   eInFlush = 1,      // the Flush() method is on the call stack
   eInDocUpdate = 2,  // inside an update batch on the document
   eNotifying = 3     // flushing pending append notifications
 };
 
 class nsHtml5DocumentBuilder : public nsContentSink
 {
-  using Encoding = mozilla::Encoding;
-  template <typename T> using NotNull = mozilla::NotNull<T>;
 public:
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHtml5DocumentBuilder,
                                            nsContentSink)
 
   NS_DECL_ISUPPORTS_INHERITED
 
   inline void HoldElement(already_AddRefed<nsIContent> aContent)
   {
@@ -84,18 +82,17 @@ public:
     }
   }
 
   bool IsInDocUpdate()
   {
     return mFlushState == eInDocUpdate;
   }
 
-  void SetDocumentCharsetAndSource(NotNull<const Encoding*> aEncoding,
-                                   int32_t aCharsetSource);
+  void SetDocumentCharsetAndSource(nsACString& aCharset, int32_t aCharsetSource);
 
   /**
    * Sets up style sheet load / parse
    */
   void UpdateStyleSheet(nsIContent* aElement);
 
   void SetDocumentMode(nsHtml5DocumentMode m);
 
--- a/parser/html/nsHtml5MetaScanner.cpp
+++ b/parser/html/nsHtml5MetaScanner.cpp
@@ -72,17 +72,16 @@ nsHtml5MetaScanner::nsHtml5MetaScanner(n
   , contentTypeIndex(INT32_MAX)
   , stateSave(DATA)
   , strBufLen(0)
   , strBuf(jArray<char16_t, int32_t>::newJArray(36))
   , content(nullptr)
   , charset(nullptr)
   , httpEquivState(HTTP_EQUIV_NOT_SEEN)
   , treeBuilder(tb)
-  , mEncoding(nullptr)
 {
   MOZ_COUNT_CTOR(nsHtml5MetaScanner);
 }
 
 
 nsHtml5MetaScanner::~nsHtml5MetaScanner()
 {
   MOZ_COUNT_DTOR(nsHtml5MetaScanner);
--- a/parser/html/nsHtml5MetaScannerCppSupplement.h
+++ b/parser/html/nsHtml5MetaScannerCppSupplement.h
@@ -1,44 +1,44 @@
 /* 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 "nsISupportsImpl.h"
 
 #include "mozilla/Encoding.h"
 
-const Encoding*
-nsHtml5MetaScanner::sniff(nsHtml5ByteReadable* bytes)
+void
+nsHtml5MetaScanner::sniff(nsHtml5ByteReadable* bytes, nsACString& charset)
 {
   readable = bytes;
   stateLoop(stateSave);
   readable = nullptr;
-  return mEncoding;
+  charset.Assign(mCharset);
 }
 
 bool
 nsHtml5MetaScanner::tryCharset(nsHtml5String charset)
 {
   // This code needs to stay in sync with
   // nsHtml5StreamParser::internalEncodingDeclaration. Unfortunately, the
   // trickery with member fields here leads to some copy-paste reuse. :-(
   nsAutoCString label;
   nsString charset16; // Not Auto, because using it to hold nsStringBuffer*
   charset.ToString(charset16);
   CopyUTF16toUTF8(charset16, label);
-  const Encoding* encoding = Encoding::ForLabel(label);
+  const mozilla::Encoding* encoding = mozilla::Encoding::ForLabel(label);
   if (!encoding) {
     return false;
   }
   if (encoding == UTF_16BE_ENCODING ||
       encoding == UTF_16LE_ENCODING) {
-    mEncoding = UTF_8_ENCODING;
+    mCharset.AssignLiteral("UTF-8");
     return true;
   }
   if (encoding == X_USER_DEFINED_ENCODING) {
     // WebKit/Blink hack for Indian and Armenian legacy sites
-    mEncoding = WINDOWS_1252_ENCODING;
+    mCharset.AssignLiteral("windows-1252");
     return true;
   }
-  mEncoding = encoding;
+  encoding->Name(mCharset);
   return true;
 }
--- a/parser/html/nsHtml5MetaScannerHSupplement.h
+++ b/parser/html/nsHtml5MetaScannerHSupplement.h
@@ -1,12 +1,12 @@
 /* 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/. */
-  using Encoding = mozilla::Encoding;
+ 
 private:
-  const Encoding* mEncoding;
+  nsCString mCharset;
   inline int32_t read()
   {
     return readable->read();
   }
 public:
-  const Encoding* sniff(nsHtml5ByteReadable* bytes);
+  void sniff(nsHtml5ByteReadable* bytes, nsACString& charset);
--- a/parser/html/nsHtml5Parser.cpp
+++ b/parser/html/nsHtml5Parser.cpp
@@ -94,25 +94,29 @@ nsHtml5Parser::SetCommand(const char* aC
 
 NS_IMETHODIMP_(void)
 nsHtml5Parser::SetCommand(eParserCommands aParserCommand)
 {
   NS_ASSERTION(aParserCommand == eViewNormal,
                "Parser command was not eViewNormal.");
 }
 
-void
-nsHtml5Parser::SetDocumentCharset(NotNull<const Encoding*> aEncoding,
+NS_IMETHODIMP_(void)
+nsHtml5Parser::SetDocumentCharset(const nsACString& aCharset,
                                   int32_t aCharsetSource)
 {
   NS_PRECONDITION(!mExecutor->HasStarted(),
                   "Document charset set too late.");
   NS_PRECONDITION(GetStreamParser(), "Setting charset on a script-only parser.");
-  GetStreamParser()->SetDocumentCharset(aEncoding, aCharsetSource);
-  mExecutor->SetDocumentCharsetAndSource(aEncoding, aCharsetSource);
+  nsAutoCString trimmed;
+  trimmed.Assign(aCharset);
+  trimmed.Trim(" \t\r\n\f");
+  GetStreamParser()->SetDocumentCharset(trimmed, aCharsetSource);
+  mExecutor->SetDocumentCharsetAndSource(trimmed,
+                                         aCharsetSource);
 }
 
 NS_IMETHODIMP
 nsHtml5Parser::GetChannel(nsIChannel** aChannel)
 {
   if (GetStreamParser()) {
     return GetStreamParser()->GetChannel(aChannel);
   } else {
--- a/parser/html/nsHtml5Parser.h
+++ b/parser/html/nsHtml5Parser.h
@@ -62,21 +62,28 @@ class nsHtml5Parser final : public nsIPa
      * No-op for backwards compat.
      */
     NS_IMETHOD_(void) SetCommand(eParserCommands aParserCommand) override;
 
     /**
      *  Call this method once you've created a parser, and want to instruct it
      *  about what charset to load
      *
-     *  @param   aEncoding the charset of a document
+     *  @param   aCharset the charset of a document
      *  @param   aCharsetSource the source of the charset
      */
-    virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding,
-                                    int32_t aSource) override;
+    NS_IMETHOD_(void) SetDocumentCharset(const nsACString& aCharset, int32_t aSource) override;
+
+    /**
+     * Don't call. For interface compat only.
+     */
+    NS_IMETHOD_(void) GetDocumentCharset(nsACString& aCharset, int32_t& aSource) override
+    {
+      NS_NOTREACHED("No one should call this.");
+    }
 
     /**
      * Get the channel associated with this parser
      * @param aChannel out param that will contain the result
      * @return NS_OK if successful or NS_NOT_AVAILABLE if not
      */
     NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
 
--- a/parser/html/nsHtml5SpeculativeLoad.cpp
+++ b/parser/html/nsHtml5SpeculativeLoad.cpp
@@ -61,17 +61,17 @@ nsHtml5SpeculativeLoad::Perform(nsHtml5T
       aExecutor->ProcessOfflineManifest(mUrl);
       break;
     case eSpeculativeLoadSetDocumentCharset: {
         nsAutoCString narrowName;
         CopyUTF16toUTF8(mCharset, narrowName);
         NS_ASSERTION(mTypeOrCharsetSourceOrDocumentMode.Length() == 1,
             "Unexpected charset source string");
         int32_t intSource = (int32_t)mTypeOrCharsetSourceOrDocumentMode.First();
-        aExecutor->SetDocumentCharsetAndSource(Encoding::ForName(narrowName),
+        aExecutor->SetDocumentCharsetAndSource(narrowName,
                                                intSource);
       }
       break;
     case eSpeculativeLoadSetDocumentMode: {
         NS_ASSERTION(mTypeOrCharsetSourceOrDocumentMode.Length() == 1,
             "Unexpected document mode string");
         nsHtml5DocumentMode mode =
             (nsHtml5DocumentMode)mTypeOrCharsetSourceOrDocumentMode.First();
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -147,17 +147,16 @@ class nsHtml5LoadFlusher : public Runnab
 };
 
 nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
                                          nsHtml5Parser* aOwner,
                                          eParserMode aMode)
   : mSniffingLength(0)
   , mBomState(eBomState::BOM_SNIFFING_NOT_STARTED)
   , mCharsetSource(kCharsetUninitialized)
-  , mEncoding(WINDOWS_1252_ENCODING)
   , mReparseForbidden(false)
   , mLastBuffer(nullptr) // Will be filled when starting
   , mExecutor(aExecutor)
   , mTreeBuilder(new nsHtml5TreeBuilder((aMode == VIEW_SOURCE_HTML ||
                                          aMode == VIEW_SOURCE_XML) ?
                                              nullptr : mExecutor->GetStage(),
                                          aMode == NORMAL ?
                                              mExecutor->GetStage() : nullptr))
@@ -249,42 +248,44 @@ nsHtml5StreamParser::GetChannel(nsIChann
 }
 
 NS_IMETHODIMP
 nsHtml5StreamParser::Notify(const char* aCharset, nsDetectionConfident aConf)
 {
   NS_ASSERTION(IsParserThread(), "Wrong thread!");
   if (aConf == eBestAnswer || aConf == eSureAnswer) {
     mFeedChardet = false; // just in case
-    auto encoding = Encoding::ForLabelNoReplacement(
+    const Encoding* encoding = Encoding::ForLabelNoReplacement(
         nsDependentCString(aCharset));
     if (!encoding) {
       return NS_OK;
     }
+    nsAutoCString charset;
+    encoding->Name(charset);
     if (HasDecoder()) {
-      if (mEncoding == encoding) {
+      if (mCharset.Equals(charset)) {
         NS_ASSERTION(mCharsetSource < kCharsetFromAutoDetection,
             "Why are we running chardet at all?");
         mCharsetSource = kCharsetFromAutoDetection;
-        mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource);
+        mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
       } else {
         // We've already committed to a decoder. Request a reload from the
         // docshell.
-        mTreeBuilder->NeedsCharsetSwitchTo(WrapNotNull(encoding),
+        mTreeBuilder->NeedsCharsetSwitchTo(charset,
                                            kCharsetFromAutoDetection,
                                            0);
         FlushTreeOpsAndDisarmTimer();
         Interrupt();
       }
     } else {
       // Got a confident answer from the sniffing buffer. That code will
       // take care of setting up the decoder.
-      mEncoding = WrapNotNull(encoding);
+      mCharset.Assign(charset);
       mCharsetSource = kCharsetFromAutoDetection;
-      mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource);
+      mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
     }
   }
   return NS_OK;
 }
 
 void
 nsHtml5StreamParser::SetViewSourceTitle(nsIURI* aURL)
 {
@@ -315,39 +316,39 @@ nsHtml5StreamParser::SetViewSourceTitle(
 
 nsresult
 nsHtml5StreamParser::SetupDecodingAndWriteSniffingBufferAndCurrentSegment(const uint8_t* aFromSegment, // can be null
                                                                           uint32_t aCount,
                                                                           uint32_t* aWriteCount)
 {
   NS_ASSERTION(IsParserThread(), "Wrong thread!");
   nsresult rv = NS_OK;
-  mUnicodeDecoder = mEncoding->NewDecoderWithBOMRemoval();
+  mUnicodeDecoder = Encoding::ForName(mCharset)->NewDecoderWithBOMRemoval();
   if (mSniffingBuffer) {
     uint32_t writeCount;
     rv = WriteStreamBytes(mSniffingBuffer.get(), mSniffingLength, &writeCount);
     NS_ENSURE_SUCCESS(rv, rv);
     mSniffingBuffer = nullptr;
   }
   mMetaScanner = nullptr;
   if (aFromSegment) {
     rv = WriteStreamBytes(aFromSegment, aCount, aWriteCount);
   }
   return rv;
 }
 
 nsresult
-nsHtml5StreamParser::SetupDecodingFromBom(NotNull<const Encoding*> aEncoding)
+nsHtml5StreamParser::SetupDecodingFromBom(const char* aDecoderCharsetName)
 {
   NS_ASSERTION(IsParserThread(), "Wrong thread!");
-  mEncoding = aEncoding;
-  mUnicodeDecoder = mEncoding->NewDecoderWithBOMRemoval();
+  mCharset.Assign(aDecoderCharsetName);
+  mUnicodeDecoder = Encoding::ForName(mCharset)->NewDecoderWithBOMRemoval();
   mCharsetSource = kCharsetFromByteOrderMark;
   mFeedChardet = false;
-  mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource);
+  mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
   mSniffingBuffer = nullptr;
   mMetaScanner = nullptr;
   mBomState = BOM_SNIFFING_OVER;
   return NS_OK;
 }
 
 void
 nsHtml5StreamParser::SniffBOMlessUTF16BasicLatin(const uint8_t* aFromSegment,
@@ -392,48 +393,47 @@ nsHtml5StreamParser::SniffBOMlessUTF16Ba
           return;
         }
         byteZero[(i + j) % 2] = true;
       }
     }
   }
 
   if (byteNonZero[0]) {
-    mEncoding = UTF_16LE_ENCODING;
+    mCharset.AssignLiteral("UTF-16LE");
   } else {
-    mEncoding = UTF_16BE_ENCODING;
+    mCharset.AssignLiteral("UTF-16BE");
   }
   mCharsetSource = kCharsetFromIrreversibleAutoDetection;
-  mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource);
+  mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
   mFeedChardet = false;
   mTreeBuilder->MaybeComplainAboutCharset("EncBomlessUtf16",
                                           true,
                                           0);
 
 }
 
 void
 nsHtml5StreamParser::SetEncodingFromExpat(const char16_t* aEncoding)
 {
   if (aEncoding) {
     nsDependentString utf16(aEncoding);
     nsAutoCString utf8;
     CopyUTF16toUTF8(utf16, utf8);
-    auto encoding = PreferredForInternalEncodingDecl(utf8);
-    if (encoding) {
-      mEncoding = WrapNotNull(encoding);
+    if (PreferredForInternalEncodingDecl(utf8)) {
+      mCharset.Assign(utf8);
       mCharsetSource = kCharsetFromMetaTag; // closest for XML
       return;
     }
     // else the page declared an encoding Gecko doesn't support and we'd
     // end up defaulting to UTF-8 anyway. Might as well fall through here
     // right away and let the encoding be set to UTF-8 which we'd default to
     // anyway.
   }
-  mEncoding = UTF_8_ENCODING; // XML defaults to UTF-8 without a BOM
+  mCharset.AssignLiteral("UTF-8"); // XML defaults to UTF-8 without a BOM
   mCharsetSource = kCharsetFromMetaTag; // means confident
 }
 
 // A separate user data struct is used instead of passing the
 // nsHtml5StreamParser instance as user data in order to avoid including
 // expat.h in nsHtml5StreamParser.h. Doing that would cause naming conflicts.
 // Using a separate user data struct also avoids bloating nsHtml5StreamParser
 // by one pointer.
@@ -555,17 +555,17 @@ nsHtml5StreamParser::FinalizeSniffing(co
     }
     XML_ParserFree(ud.mExpat);
 
     if (mCharsetSource < kCharsetFromMetaTag) {
       // Failed to get an encoding from the XML declaration. XML defaults
       // confidently to UTF-8 in this case.
       // It is also possible that the document has an XML declaration that is
       // longer than 1024 bytes, but that case is not worth worrying about.
-      mEncoding = UTF_8_ENCODING;
+      mCharset.AssignLiteral("UTF-8");
       mCharsetSource = kCharsetFromMetaTag; // means confident
     }
 
     return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment,
                                                                 aCount,
                                                                 aWriteCount);
   }
 
@@ -607,44 +607,44 @@ nsHtml5StreamParser::FinalizeSniffing(co
       mFeedChardet = false;
       rv = mChardet->Done();
       NS_ENSURE_SUCCESS(rv, rv);
     }
     // fall thru; callback may have changed charset
   }
   if (mCharsetSource == kCharsetUninitialized) {
     // Hopefully this case is never needed, but dealing with it anyway
-    mEncoding = WINDOWS_1252_ENCODING;
+    mCharset.AssignLiteral("windows-1252");
     mCharsetSource = kCharsetFromFallback;
-    mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource);
+    mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
   } else if (mMode == LOAD_AS_DATA &&
              mCharsetSource == kCharsetFromFallback) {
     NS_ASSERTION(mReparseForbidden, "Reparse should be forbidden for XHR");
     NS_ASSERTION(!mFeedChardet, "Should not feed chardet for XHR");
-    NS_ASSERTION(mEncoding == UTF_8_ENCODING,
+    NS_ASSERTION(mCharset.EqualsLiteral("UTF-8"),
                  "XHR should default to UTF-8");
     // Now mark charset source as non-weak to signal that we have a decision
     mCharsetSource = kCharsetFromDocTypeDefault;
-    mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource);
+    mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
   }
   return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment, aCount, aWriteCount);
 }
 
 nsresult
 nsHtml5StreamParser::SniffStreamBytes(const uint8_t* aFromSegment,
                                       uint32_t aCount,
                                       uint32_t* aWriteCount)
 {
   NS_ASSERTION(IsParserThread(), "Wrong thread!");
   nsresult rv = NS_OK;
   uint32_t writeCount;
 
-  // mEncoding and mCharsetSource potentially have come from channel or higher
+  // mCharset and mCharsetSource potentially have come from channel or higher
   // by now. If we find a BOM, SetupDecodingFromBom() will overwrite them.
-  // If we don't find a BOM, the previously set values of mEncoding and
+  // If we don't find a BOM, the previously set values of mCharset and
   // mCharsetSource are not modified by the BOM sniffing here.
   for (uint32_t i = 0; i < aCount && mBomState != BOM_SNIFFING_OVER; i++) {
     switch (mBomState) {
       case BOM_SNIFFING_NOT_STARTED:
         NS_ASSERTION(i == 0, "Bad BOM sniffing state.");
         switch (*aFromSegment) {
           case 0xEF:
             mBomState = SEEN_UTF_8_FIRST_BYTE;
@@ -657,29 +657,29 @@ nsHtml5StreamParser::SniffStreamBytes(co
             break;
           default:
             mBomState = BOM_SNIFFING_OVER;
             break;
         }
         break;
       case SEEN_UTF_16_LE_FIRST_BYTE:
         if (aFromSegment[i] == 0xFE) {
-          rv = SetupDecodingFromBom(UTF_16LE_ENCODING); // upper case is the raw form
+          rv = SetupDecodingFromBom("UTF-16LE"); // upper case is the raw form
           NS_ENSURE_SUCCESS(rv, rv);
           uint32_t count = aCount - (i + 1);
           rv = WriteStreamBytes(aFromSegment + (i + 1), count, &writeCount);
           NS_ENSURE_SUCCESS(rv, rv);
           *aWriteCount = writeCount + (i + 1);
           return rv;
         }
         mBomState = BOM_SNIFFING_OVER;
         break;
       case SEEN_UTF_16_BE_FIRST_BYTE:
         if (aFromSegment[i] == 0xFF) {
-          rv = SetupDecodingFromBom(UTF_16BE_ENCODING); // upper case is the raw form
+          rv = SetupDecodingFromBom("UTF-16BE"); // upper case is the raw form
           NS_ENSURE_SUCCESS(rv, rv);
           uint32_t count = aCount - (i + 1);
           rv = WriteStreamBytes(aFromSegment + (i + 1), count, &writeCount);
           NS_ENSURE_SUCCESS(rv, rv);
           *aWriteCount = writeCount + (i + 1);
           return rv;
         }
         mBomState = BOM_SNIFFING_OVER;
@@ -688,17 +688,17 @@ nsHtml5StreamParser::SniffStreamBytes(co
         if (aFromSegment[i] == 0xBB) {
           mBomState = SEEN_UTF_8_SECOND_BYTE;
         } else {
           mBomState = BOM_SNIFFING_OVER;
         }
         break;
       case SEEN_UTF_8_SECOND_BYTE:
         if (aFromSegment[i] == 0xBF) {
-          rv = SetupDecodingFromBom(UTF_8_ENCODING); // upper case is the raw form
+          rv = SetupDecodingFromBom("UTF-8"); // upper case is the raw form
           NS_ENSURE_SUCCESS(rv, rv);
           uint32_t count = aCount - (i + 1);
           rv = WriteStreamBytes(aFromSegment + (i + 1), count, &writeCount);
           NS_ENSURE_SUCCESS(rv, rv);
           *aWriteCount = writeCount + (i + 1);
           return rv;
         }
         mBomState = BOM_SNIFFING_OVER;
@@ -713,23 +713,23 @@ nsHtml5StreamParser::SniffStreamBytes(co
 
   MOZ_ASSERT(mCharsetSource != kCharsetFromByteOrderMark,
              "Should not come here if BOM was found.");
   MOZ_ASSERT(mCharsetSource != kCharsetFromOtherComponent,
              "kCharsetFromOtherComponent is for XSLT.");
 
   if (mBomState == BOM_SNIFFING_OVER &&
     mCharsetSource == kCharsetFromChannel) {
-    // There was no BOM and the charset came from channel. mEncoding
+    // There was no BOM and the charset came from channel. mCharset
     // still contains the charset from the channel as set by an
     // earlier call to SetDocumentCharset(), since we didn't find a BOM and
-    // overwrite mEncoding. (Note that if the user has overridden the charset,
+    // overwrite mCharset. (Note that if the user has overridden the charset,
     // we don't come here but check <meta> for XSS-dangerous charsets first.)
     mFeedChardet = false;
-    mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource);
+    mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
     return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment,
       aCount, aWriteCount);
   }
 
   if (!mMetaScanner && (mMode == NORMAL ||
                         mMode == VIEW_SOURCE_HTML ||
                         mMode == LOAD_AS_DATA)) {
     mMetaScanner = new nsHtml5MetaScanner(mTreeBuilder);
@@ -738,37 +738,38 @@ nsHtml5StreamParser::SniffStreamBytes(co
   if (mSniffingLength + aCount >= NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE) {
     // this is the last buffer
     uint32_t countToSniffingLimit =
         NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE - mSniffingLength;
     if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML || mMode == LOAD_AS_DATA) {
       nsHtml5ByteReadable readable(aFromSegment, aFromSegment +
           countToSniffingLimit);
       nsAutoCString charset;
-      auto encoding = mMetaScanner->sniff(&readable);
+      mMetaScanner->sniff(&readable, charset);
       // Due to the way nsHtml5Portability reports OOM, ask the tree buider
       nsresult rv;
       if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
         MarkAsBroken(rv);
         return rv;
       }
-      if (encoding) {
+      if (!charset.IsEmpty()) {
+        const Encoding* encoding = Encoding::ForName(charset);
         // meta scan successful; honor overrides unless meta is XSS-dangerous
         if ((mCharsetSource == kCharsetFromParentForced ||
              mCharsetSource == kCharsetFromUserForced) &&
             (encoding->IsAsciiCompatible() ||
              encoding == ISO_2022_JP_ENCODING)) {
           // Honor override
           return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(
             aFromSegment, aCount, aWriteCount);
         }
-        mEncoding = WrapNotNull(encoding);
+        mCharset.Assign(charset);
         mCharsetSource = kCharsetFromMetaPrescan;
         mFeedChardet = false;
-        mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource);
+        mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
         return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(
           aFromSegment, aCount, aWriteCount);
       }
     }
     if (mCharsetSource == kCharsetFromParentForced ||
         mCharsetSource == kCharsetFromUserForced) {
       // meta not found, honor override
       return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(
@@ -776,37 +777,39 @@ nsHtml5StreamParser::SniffStreamBytes(co
     }
     return FinalizeSniffing(aFromSegment, aCount, aWriteCount,
         countToSniffingLimit);
   }
 
   // not the last buffer
   if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML || mMode == LOAD_AS_DATA) {
     nsHtml5ByteReadable readable(aFromSegment, aFromSegment + aCount);
-    auto encoding = mMetaScanner->sniff(&readable);
+    nsAutoCString charset;
+    mMetaScanner->sniff(&readable, charset);
     // Due to the way nsHtml5Portability reports OOM, ask the tree buider
     nsresult rv;
     if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
       MarkAsBroken(rv);
       return rv;
     }
-    if (encoding) {
+    if (!charset.IsEmpty()) {
+      const Encoding* encoding = Encoding::ForName(charset);
       // meta scan successful; honor overrides unless meta is XSS-dangerous
       if ((mCharsetSource == kCharsetFromParentForced ||
            mCharsetSource == kCharsetFromUserForced) &&
           (encoding->IsAsciiCompatible() ||
            encoding == ISO_2022_JP_ENCODING)) {
         // Honor override
         return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment,
             aCount, aWriteCount);
       }
-      mEncoding = WrapNotNull(encoding);
+      mCharset.Assign(charset);
       mCharsetSource = kCharsetFromMetaPrescan;
       mFeedChardet = false;
-      mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource);
+      mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
       return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment,
         aCount, aWriteCount);
     }
   }
 
   if (!mSniffingBuffer) {
     mSniffingBuffer =
       MakeUniqueFallible<uint8_t[]>(NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE);
@@ -999,17 +1002,17 @@ nsHtml5StreamParser::OnStartRequest(nsIR
 
   // We are reloading a document.open()ed doc or loading JSON/WebVTT/etc. into
   // a browsing context. In the latter case, there's no need to remove the
   // BOM manually here, because the UTF-8 decoder removes it.
   mReparseForbidden = true;
   mFeedChardet = false;
 
   // Instantiate the converter here to avoid BOM sniffing.
-  mUnicodeDecoder = mEncoding->NewDecoderWithBOMRemoval();
+  mUnicodeDecoder = Encoding::ForName(mCharset)->NewDecoderWithBOMRemoval();
   return NS_OK;
 }
 
 nsresult
 nsHtml5StreamParser::CheckListenerChain()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread!");
   if (!mObserver) {
@@ -1223,26 +1226,26 @@ nsHtml5StreamParser::CopySegmentsToParse
   nsHtml5StreamParser* parser = static_cast<nsHtml5StreamParser*>(aClosure);
 
   parser->DoDataAvailable((const uint8_t*)aFromSegment, aCount);
   // Assume DoDataAvailable consumed all available bytes.
   *aWriteCount = aCount;
   return NS_OK;
 }
 
-const Encoding*
-nsHtml5StreamParser::PreferredForInternalEncodingDecl(const nsACString& aEncoding)
+bool
+nsHtml5StreamParser::PreferredForInternalEncodingDecl(nsACString& aEncoding)
 {
   const Encoding* newEncoding = Encoding::ForLabel(aEncoding);
   if (!newEncoding) {
     // the encoding name is bogus
     mTreeBuilder->MaybeComplainAboutCharset("EncMetaUnsupported",
                                             true,
                                             mTokenizer->getLineNumber());
-    return nullptr;
+    return false;
   }
 
   if (newEncoding == UTF_16BE_ENCODING ||
       newEncoding == UTF_16LE_ENCODING) {
     mTreeBuilder->MaybeComplainAboutCharset("EncMetaUtf16",
                                             true,
                                             mTokenizer->getLineNumber());
     newEncoding = UTF_8_ENCODING;
@@ -1251,34 +1254,35 @@ nsHtml5StreamParser::PreferredForInterna
   if (newEncoding == X_USER_DEFINED_ENCODING) {
     // WebKit/Blink hack for Indian and Armenian legacy sites
     mTreeBuilder->MaybeComplainAboutCharset("EncMetaUserDefined",
                                             true,
                                             mTokenizer->getLineNumber());
     newEncoding = WINDOWS_1252_ENCODING;
   }
 
-  if (newEncoding == mEncoding) {
+  if (newEncoding == Encoding::ForName(mCharset)) {
     if (mCharsetSource < kCharsetFromMetaPrescan) {
       if (mInitialEncodingWasFromParentFrame) {
         mTreeBuilder->MaybeComplainAboutCharset("EncLateMetaFrame",
                                                 false,
                                                 mTokenizer->getLineNumber());
       } else {
         mTreeBuilder->MaybeComplainAboutCharset("EncLateMeta",
                                                 false,
                                                 mTokenizer->getLineNumber());
       }
     }
     mCharsetSource = kCharsetFromMetaTag; // become confident
     mFeedChardet = false; // don't feed chardet when confident
-    return nullptr;
+    return false;
   }
 
-  return newEncoding;
+  newEncoding->Name(aEncoding);
+  return true;
 }
 
 bool
 nsHtml5StreamParser::internalEncodingDeclaration(nsHtml5String aEncoding)
 {
   // This code needs to stay in sync with
   // nsHtml5MetaScanner::tryCharset. Unfortunately, the
   // trickery with member fields there leads to some copy-paste reuse. :-(
@@ -1287,18 +1291,17 @@ nsHtml5StreamParser::internalEncodingDec
     return false;
   }
 
   nsString newEncoding16; // Not Auto, because using it to hold nsStringBuffer*
   aEncoding.ToString(newEncoding16);
   nsAutoCString newEncoding;
   CopyUTF16toUTF8(newEncoding16, newEncoding);
 
-  auto encoding = PreferredForInternalEncodingDecl(newEncoding);
-  if (!encoding) {
+  if (!PreferredForInternalEncodingDecl(newEncoding)) {
     return false;
   }
 
   if (mReparseForbidden) {
     // This mReparseForbidden check happens after the call to
     // PreferredForInternalEncodingDecl so that if that method calls
     // MaybeComplainAboutCharset, its charset complaint wins over the one
     // below.
@@ -1306,17 +1309,17 @@ nsHtml5StreamParser::internalEncodingDec
                                             true,
                                             mTokenizer->getLineNumber());
     return false; // not reparsing even if we wanted to
   }
 
   // Avoid having the chardet ask for another restart after this restart
   // request.
   mFeedChardet = false;
-  mTreeBuilder->NeedsCharsetSwitchTo(WrapNotNull(encoding),
+  mTreeBuilder->NeedsCharsetSwitchTo(newEncoding,
                                      kCharsetFromMetaTag,
                                      mTokenizer->getLineNumber());
   FlushTreeOpsAndDisarmTimer();
   Interrupt();
   // the tree op executor will cause the stream parser to terminate
   // if the charset switch request is accepted or it'll uninterrupt
   // if the request failed. Note that if the restart request fails,
   // we don't bother trying to make chardet resume. Might as well
--- a/parser/html/nsHtml5StreamParser.h
+++ b/parser/html/nsHtml5StreamParser.h
@@ -96,19 +96,17 @@ enum eBomState {
 };
 
 enum eHtml5StreamState {
   STREAM_NOT_STARTED = 0,
   STREAM_BEING_READ = 1,
   STREAM_ENDED = 2
 };
 
-class nsHtml5StreamParser final : public nsICharsetDetectionObserver {
-  template <typename T> using NotNull = mozilla::NotNull<T>;
-  using Encoding = mozilla::Encoding;
+class nsHtml5StreamParser : public nsICharsetDetectionObserver {
 
   friend class nsHtml5RequestStopper;
   friend class nsHtml5DataAvailable;
   friend class nsHtml5StreamParserContinuation;
   friend class nsHtml5TimerKungFu;
 
   public:
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -150,25 +148,24 @@ class nsHtml5StreamParser final : public
     bool internalEncodingDeclaration(nsHtml5String aEncoding);
 
     // Not from an external interface
 
     /**
      *  Call this method once you've created a parser, and want to instruct it
      *  about what charset to load
      *
-     *  @param   aEncoding the charset of a document
+     *  @param   aCharset the charset of a document
      *  @param   aCharsetSource the source of the charset
      */
-    inline void SetDocumentCharset(NotNull<const Encoding*> aEncoding,
-                                   int32_t aSource) {
+    inline void SetDocumentCharset(const nsACString& aCharset, int32_t aSource) {
       NS_PRECONDITION(mStreamState == STREAM_NOT_STARTED,
                       "SetDocumentCharset called too late.");
       NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-      mEncoding = aEncoding;
+      mCharset = aCharset;
       mCharsetSource = aSource;
     }
     
     inline void SetObserver(nsIRequestObserver* aObserver) {
       NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
       mObserver = aObserver;
     }
 
@@ -192,19 +189,19 @@ class nsHtml5StreamParser final : public
     {
       mozilla::MutexAutoLock autoLock(mTerminatedMutex);
       mTerminated = true;
     }
     
     void DropTimer();
 
     /**
-     * Sets mEncoding and mCharsetSource appropriately for the XML View Source
+     * Sets mCharset and mCharsetSource appropriately for the XML View Source
      * case if aEncoding names a supported rough ASCII superset and sets
-     * the mEncoding and mCharsetSource to the UTF-8 default otherwise.
+     * the mCharset and mCharsetSource to the UTF-8 default otherwise.
      */
     void SetEncodingFromExpat(const char16_t* aEncoding);
 
     /**
      * Sets the URL for View Source title in case this parser ends up being
      * used for View Source. If aURL is a view-source: URL, takes the inner
      * URL. data: URLs are shown with an ellipsis instead of the actual data.
      */
@@ -337,27 +334,27 @@ class nsHtml5StreamParser final : public
     /**
      * Initialize the Unicode decoder, mark the BOM as the source and
      * drop the sniffer.
      *
      * @param aDecoderCharsetName The name for the decoder's charset
      *                            (UTF-16BE, UTF-16LE or UTF-8; the BOM has
      *                            been swallowed)
      */
-    nsresult SetupDecodingFromBom(NotNull<const Encoding*> aEncoding);
+    nsresult SetupDecodingFromBom(const char* aDecoderCharsetName);
 
     /**
      * Become confident or resolve and encoding name to its preferred form.
      * @param aEncoding the value of an internal encoding decl. Acts as an
      *                  out param, too, when the method returns true.
      * @return true if the parser needs to start using the new value of
      *         aEncoding and false if the parser became confident or if
      *         the encoding name did not specify a usable encoding
      */
-    const Encoding* PreferredForInternalEncodingDecl(const nsACString& aEncoding);
+    bool PreferredForInternalEncodingDecl(nsACString& aEncoding);
 
     /**
      * Callback for mFlushTimer.
      */
     static void TimerCallback(nsITimer* aTimer, void* aClosure);
 
     /**
      * Parser thread entry point for (maybe) flushing the ops and posting
@@ -421,17 +418,17 @@ class nsHtml5StreamParser final : public
     /**
      * The source (confidence) of the character encoding in use
      */
     int32_t                       mCharsetSource;
 
     /**
      * The character encoding in use
      */
-    NotNull<const Encoding*>      mEncoding;
+    nsCString                     mCharset;
 
     /**
      * Whether reparse is forbidden
      */
     bool                          mReparseForbidden;
 
     // Portable parser objects
     /**
--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h
@@ -1073,55 +1073,53 @@ nsHtml5TreeBuilder::FlushLoads()
     return;
   }
   if (!mSpeculativeLoadQueue.IsEmpty()) {
     mSpeculativeLoadStage->MoveSpeculativeLoadsFrom(mSpeculativeLoadQueue);
   }
 }
 
 void
-nsHtml5TreeBuilder::SetDocumentCharset(NotNull<const Encoding*> aEncoding, 
+nsHtml5TreeBuilder::SetDocumentCharset(nsACString& aCharset, 
                                        int32_t aCharsetSource)
 {
   if (mBuilder) {
-    mBuilder->SetDocumentCharsetAndSource(aEncoding, aCharsetSource);
+    mBuilder->SetDocumentCharsetAndSource(aCharset, aCharsetSource);
   } else if (mSpeculativeLoadStage) {
-    nsAutoCString charset;
-    aEncoding->Name(charset);
     mSpeculativeLoadQueue.AppendElement()->InitSetDocumentCharset(
-      charset, aCharsetSource);
+      aCharset, aCharsetSource);
   } else {
     mOpQueue.AppendElement()->Init(
-      eTreeOpSetDocumentCharset, aEncoding, aCharsetSource);
+      eTreeOpSetDocumentCharset, aCharset, aCharsetSource);
   }
 }
 
 void
 nsHtml5TreeBuilder::StreamEnded()
 {
   MOZ_ASSERT(!mBuilder, "Must not call StreamEnded with builder.");
   MOZ_ASSERT(!fragment, "Must not parse fragments off the main thread.");
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(eTreeOpStreamEnded);
 }
 
 void
-nsHtml5TreeBuilder::NeedsCharsetSwitchTo(NotNull<const Encoding*> aEncoding,
+nsHtml5TreeBuilder::NeedsCharsetSwitchTo(const nsACString& aCharset,
                                          int32_t aCharsetSource,
                                          int32_t aLineNumber)
 {
   if (MOZ_UNLIKELY(mBuilder)) {
     MOZ_ASSERT_UNREACHABLE("Must never switch charset with builder.");
     return;
   }
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(eTreeOpNeedsCharsetSwitchTo,
-               aEncoding,
+               aCharset,
                aCharsetSource,
                aLineNumber);
 }
 
 void
 nsHtml5TreeBuilder::MaybeComplainAboutCharset(const char* aMsgId,
                                               bool aError,
                                               int32_t aLineNumber)
--- a/parser/html/nsHtml5TreeBuilderHSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderHSupplement.h
@@ -1,17 +1,15 @@
 /* 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/. */
 
 #define NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH 512
+
   private:
-    using Encoding = mozilla::Encoding;
-    template <typename T> using NotNull = mozilla::NotNull<T>;
-
     nsHtml5OplessBuilder*                  mBuilder;
     // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     // If mBuilder is not null, the tree op machinery is not in use and
     // the fields below aren't in use, either.
     // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     nsHtml5Highlighter*                    mViewSource;
     nsTArray<nsHtml5TreeOperation>         mOpQueue;
     nsTArray<nsHtml5SpeculativeLoad>       mSpeculativeLoadQueue;
@@ -101,22 +99,21 @@
     {
       mOpQueue.Clear();
     }
     
     bool Flush(bool aDiscretionary = false);
     
     void FlushLoads();
 
-    void SetDocumentCharset(NotNull<const Encoding*> aEncoding,
-                            int32_t aCharsetSource);
+    void SetDocumentCharset(nsACString& aCharset, int32_t aCharsetSource);
 
     void StreamEnded();
 
-    void NeedsCharsetSwitchTo(NotNull<const Encoding*> aEncoding,
+    void NeedsCharsetSwitchTo(const nsACString& aEncoding,
                               int32_t aSource,
                               int32_t aLineNumber);
 
     void MaybeComplainAboutCharset(const char* aMsgId,
                                    bool aError,
                                    int32_t aLineNumber);
 
     void AddSnapshotToScript(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine);
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -715,17 +715,17 @@ nsHtml5TreeOpExecutor::RunScript(nsICont
 void
 nsHtml5TreeOpExecutor::Start()
 {
   NS_PRECONDITION(!mStarted, "Tried to start when already started.");
   mStarted = true;
 }
 
 void
-nsHtml5TreeOpExecutor::NeedsCharsetSwitchTo(NotNull<const Encoding*> aEncoding,
+nsHtml5TreeOpExecutor::NeedsCharsetSwitchTo(const char* aEncoding,
                                             int32_t aSource,
                                             uint32_t aLineNumber)
 {
   EndDocUpdate();
 
   if (MOZ_UNLIKELY(!mParser)) {
     // got terminate
     return;
@@ -733,19 +733,17 @@ nsHtml5TreeOpExecutor::NeedsCharsetSwitc
   
   nsCOMPtr<nsIWebShellServices> wss = do_QueryInterface(mDocShell);
   if (!wss) {
     return;
   }
 
   // ask the webshellservice to load the URL
   if (NS_SUCCEEDED(wss->StopDocumentLoad())) {
-    nsAutoCString charset;
-    aEncoding->Name(charset);
-    wss->ReloadDocument(charset.get(), aSource);
+    wss->ReloadDocument(aEncoding, aSource);
   }
   // if the charset switch was accepted, wss has called Terminate() on the
   // parser by now
 
   if (!mParser) {
     // success
     if (aSource == kCharsetFromMetaTag) {
       MaybeComplainAboutCharset("EncLateMetaReload", false, aLineNumber);
@@ -909,19 +907,19 @@ nsHtml5TreeOpExecutor::BaseURIForPreload
 already_AddRefed<nsIURI>
 nsHtml5TreeOpExecutor::ConvertIfNotPreloadedYet(const nsAString& aURL)
 {
   if (aURL.IsEmpty()) {
     return nullptr;
   }
 
   nsIURI* base = BaseURIForPreload();
-  auto encoding = mDocument->GetDocumentCharacterSet();
+  const nsCString& charset = mDocument->GetDocumentCharacterSet();
   nsCOMPtr<nsIURI> uri;
-  nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, encoding, base);
+  nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, charset.get(), base);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to create a URI");
     return nullptr;
   }
 
   if (ShouldPreloadURI(uri)) {
     return uri.forget();
   }
@@ -1013,33 +1011,33 @@ void
 nsHtml5TreeOpExecutor::PreloadEndPicture()
 {
   mDocument->PreloadPictureClosed();
 }
 
 void
 nsHtml5TreeOpExecutor::AddBase(const nsAString& aURL)
 {
-  auto encoding = mDocument->GetDocumentCharacterSet();
+  const nsCString& charset = mDocument->GetDocumentCharacterSet();
   nsresult rv = NS_NewURI(getter_AddRefs(mViewSourceBaseURI), aURL,
-                          encoding, GetViewSourceBaseURI());
+                                     charset.get(), GetViewSourceBaseURI());
   if (NS_FAILED(rv)) {
     mViewSourceBaseURI = nullptr;
   }
 }
 void
 nsHtml5TreeOpExecutor::SetSpeculationBase(const nsAString& aURL)
 {
   if (mSpeculationBaseURI) {
     // the first one wins
     return;
   }
-  auto encoding = mDocument->GetDocumentCharacterSet();
+  const nsCString& charset = mDocument->GetDocumentCharacterSet();
   DebugOnly<nsresult> rv = NS_NewURI(getter_AddRefs(mSpeculationBaseURI), aURL,
-                                     encoding, mDocument->GetDocumentURI());
+                                     charset.get(), mDocument->GetDocumentURI());
   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to create a URI");
 }
 
 void
 nsHtml5TreeOpExecutor::SetSpeculationReferrerPolicy(const nsAString& aReferrerPolicy)
 {
   // Specs says:
   // - Let value be the result of stripping leading and trailing whitespace from
--- a/parser/html/nsHtml5TreeOpExecutor.h
+++ b/parser/html/nsHtml5TreeOpExecutor.h
@@ -31,18 +31,16 @@ class nsIDocument;
 
 class nsHtml5TreeOpExecutor final : public nsHtml5DocumentBuilder,
                                     public nsIContentSink,
                                     public nsAHtml5TreeOpSink,
                                     public mozilla::LinkedListElement<nsHtml5TreeOpExecutor>
 {
   friend class nsHtml5FlushLoopGuard;
   typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
-  using nsIContentSink::Encoding;
-  using nsIContentSink::NotNull;
 
   public:
     NS_DECL_ISUPPORTS_INHERITED
 
   private:
     static bool        sExternalViewSource;
 #ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
     static uint32_t    sAppendBatchMaxSize;
@@ -137,19 +135,19 @@ class nsHtml5TreeOpExecutor final : publ
     /**
      * No-op for backwards compat.
      */
     virtual void FlushPendingNotifications(mozilla::FlushType aType) override;
 
     /**
      * Don't call. For interface compat only.
      */
-    virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override
-    {
-        NS_NOTREACHED("No one should call this.");
+    NS_IMETHOD SetDocumentCharset(nsACString& aCharset) override {
+    	NS_NOTREACHED("No one should call this.");
+    	return NS_ERROR_NOT_IMPLEMENTED;
     }
 
     /**
      * Returns the document.
      */
     virtual nsISupports *GetTarget() override;
   
     virtual void ContinueInterruptedParsingAsync() override;
@@ -181,17 +179,17 @@ class nsHtml5TreeOpExecutor final : publ
     void RunFlushLoop();
 
     nsresult FlushDocumentWrite();
 
     void MaybeSuspend();
 
     void Start();
 
-    void NeedsCharsetSwitchTo(NotNull<const Encoding*> aEncoding,
+    void NeedsCharsetSwitchTo(const char* aEncoding,
                               int32_t aSource,
                               uint32_t aLineNumber);
 
     void MaybeComplainAboutCharset(const char* aMsgId,
                                    bool aError,
                                    uint32_t aLineNumber);
 
     void ComplainAboutBogusProtocolCharset(nsIDocument* aDoc);
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -100,16 +100,17 @@ nsHtml5TreeOperation::~nsHtml5TreeOperat
     case eTreeOpAppendComment:
     case eTreeOpAppendCommentToDocument:
     case eTreeOpAddViewSourceHref:
     case eTreeOpAddViewSourceBase:
       delete[] mTwo.unicharPtr;
       break;
     case eTreeOpSetDocumentCharset:
     case eTreeOpNeedsCharsetSwitchTo:
+      delete[] mOne.charPtr;
       break;
     case eTreeOpProcessOfflineManifest:
       free(mOne.unicharPtr);
       break;
     default: // keep the compiler happy
       break;
   }
 }
@@ -783,26 +784,27 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
       return NS_OK;
     }
     case eTreeOpDoneCreatingElement: {
       nsIContent* node = *(mOne.node);
       DoneCreatingElement(node);
       return NS_OK;
     }
     case eTreeOpSetDocumentCharset: {
-      auto encoding = WrapNotNull(mOne.encoding);
+      char* str = mOne.charPtr;
       int32_t charsetSource = mFour.integer;
-      aBuilder->SetDocumentCharsetAndSource(encoding, charsetSource);
+      nsDependentCString dependentString(str);
+      aBuilder->SetDocumentCharsetAndSource(dependentString, charsetSource);
       return NS_OK;
     }
     case eTreeOpNeedsCharsetSwitchTo: {
-      auto encoding = WrapNotNull(mOne.encoding);
+      char* str = mOne.charPtr;
       int32_t charsetSource = mFour.integer;
       int32_t lineNumber = mTwo.integer;
-      aBuilder->NeedsCharsetSwitchTo(encoding, charsetSource, (uint32_t)lineNumber);
+      aBuilder->NeedsCharsetSwitchTo(str, charsetSource, (uint32_t)lineNumber);
       return NS_OK;
     }
     case eTreeOpUpdateStyleSheet: {
       nsIContent* node = *(mOne.node);
       aBuilder->UpdateStyleSheet(node);
       return NS_OK;
     }
     case eTreeOpProcessMeta: {
@@ -877,21 +879,21 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
       nsIContent* node = *mOne.node;
       char16_t* buffer = mTwo.unicharPtr;
       int32_t length = mFour.integer;
 
       nsDependentString relative(buffer, length);
 
       nsIDocument* doc = aBuilder->GetDocument();
 
-      auto encoding = doc->GetDocumentCharacterSet();
+      const nsCString& charset = doc->GetDocumentCharacterSet();
       nsCOMPtr<nsIURI> uri;
       nsresult rv = NS_NewURI(getter_AddRefs(uri),
                               relative,
-                              encoding,
+                              charset.get(),
                               aBuilder->GetViewSourceBaseURI());
       NS_ENSURE_SUCCESS(rv, NS_OK);
 
       // Reuse the fix for bug 467852
       // URLs that execute script (e.g. "javascript:" URLs) should just be
       // ignored.  There's nothing reasonable we can do with them, and allowing
       // them to execute in the context of the view-source window presents a
       // security risk.  Just return the empty string in this case.
--- a/parser/html/nsHtml5TreeOperation.h
+++ b/parser/html/nsHtml5TreeOperation.h
@@ -3,24 +3,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  
 #ifndef nsHtml5TreeOperation_h
 #define nsHtml5TreeOperation_h
 
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "mozilla/dom/FromParser.h"
-#include "mozilla/NotNull.h"
 
 class nsIContent;
 class nsHtml5TreeOpExecutor;
 class nsHtml5DocumentBuilder;
-namespace mozilla {
-class Encoding;
-}
 
 enum eHtml5TreeOperation {
   eTreeOpUninitialized,
   // main HTML5 ops
   eTreeOpAppend,
   eTreeOpDetach,
   eTreeOpAppendChildrenToNewParent,
   eTreeOpFosterParent,
@@ -84,19 +80,17 @@ class nsHtml5TreeOperationStringPair {
     
     inline void Get(nsAString& aPublicId, nsAString& aSystemId)
     {
       aPublicId.Assign(mPublicId);
       aSystemId.Assign(mSystemId);
     }
 };
 
-class nsHtml5TreeOperation final {
-    template <typename T> using NotNull = mozilla::NotNull<T>;
-    using Encoding = mozilla::Encoding;
+class nsHtml5TreeOperation {
 
   public:
     /**
      * Atom is used inside the parser core are either static atoms that are
      * the same as Gecko-wide static atoms or they are dynamic atoms scoped by
      * both thread and parser to a particular nsHtml5AtomTable. In order to
      * such scoped atoms coming into contact with the rest of Gecko, atoms
      * that are about to exit the parser must go through this method which
@@ -251,37 +245,16 @@ class nsHtml5TreeOperation final {
                      const nsACString& aString,
                      int32_t aInt32,
                      int32_t aLineNumber)
     {
       Init(aOpCode, aString, aInt32);
       mTwo.integer = aLineNumber;
     }
 
-    inline void Init(eHtml5TreeOperation aOpCode, 
-                     NotNull<const Encoding*> aEncoding,
-                     int32_t aInt32)
-    {
-      NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
-        "Op code must be uninitialized when initializing.");
-
-      mOpCode = aOpCode;
-      mOne.encoding = aEncoding;
-      mFour.integer = aInt32;
-    }
-
-    inline void Init(eHtml5TreeOperation aOpCode, 
-                     NotNull<const Encoding*> aEncoding,
-                     int32_t aInt32,
-                     int32_t aLineNumber)
-    {
-      Init(aOpCode, aEncoding, aInt32);
-      mTwo.integer = aLineNumber;
-    }
-
     inline void Init(eHtml5TreeOperation aOpCode,
                      nsIContentHandle* aNode,
                      nsIContentHandle* aParent,
                      nsIContentHandle* aTable)
     {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
@@ -529,13 +502,12 @@ class nsHtml5TreeOperation final {
       nsHtml5HtmlAttributes*          attributes;
       nsHtml5DocumentMode             mode;
       char16_t*                       unicharPtr;
       char*                           charPtr;
       nsHtml5TreeOperationStringPair* stringPair;
       nsAHtml5TreeBuilderState*       state;
       int32_t                         integer;
       nsresult                        result;
-      const Encoding*                 encoding;
     } mOne, mTwo, mThree, mFour, mFive;
 };
 
 #endif // nsHtml5TreeOperation_h
--- a/parser/htmlparser/nsIContentSink.h
+++ b/parser/htmlparser/nsIContentSink.h
@@ -14,32 +14,25 @@
  *
  * The icontentsink interface is a very lightweight wrapper that represents the
  * content-sink model building process. There is another one that you may care 
  * about more, which is the IHTMLContentSink interface. (See that file for details).
  */
 #include "nsISupports.h"
 #include "nsString.h"
 #include "mozilla/FlushType.h"
-#include "mozilla/NotNull.h"
 #include "nsIDTD.h"
 
 class nsParserBase;
-namespace mozilla {
-class Encoding;
-}
 
 #define NS_ICONTENT_SINK_IID \
 { 0xcf9a7cbb, 0xfcbc, 0x4e13, \
   { 0x8e, 0xf5, 0x18, 0xef, 0x2d, 0x3d, 0x58, 0x29 } }
 
 class nsIContentSink : public nsISupports {
-protected:
-  using Encoding = mozilla::Encoding;
-  template <typename T> using NotNull = mozilla::NotNull<T>;
 public:
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENT_SINK_IID)
 
   /**
    * This method is called by the parser when it is entered from
    * the event loop. The content sink wants to know how long the
    * parser has been active since we last processed events on the
@@ -105,17 +98,17 @@ public:
    * @param aType the type of flush to perform
    */
   virtual void FlushPendingNotifications(mozilla::FlushType aType)=0;
 
   /**
    * Set the document character set. This should be passed on to the
    * document itself.
    */
-  virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) = 0;
+  NS_IMETHOD SetDocumentCharset(nsACString& aCharset)=0;
 
   /**
    * Returns the target object (often a document object) into which
    * the content built by this content sink is being added, if any
    * (IOW, may return null).
    */
   virtual nsISupports *GetTarget()=0;
   
--- a/parser/htmlparser/nsIParser.h
+++ b/parser/htmlparser/nsIParser.h
@@ -20,30 +20,26 @@
 
 #include "nsISupports.h"
 #include "nsIStreamListener.h"
 #include "nsIDTD.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsIAtom.h"
 #include "nsParserBase.h"
-#include "mozilla/NotNull.h"
 
 #define NS_IPARSER_IID \
 { 0x2c4ad90a, 0x740e, 0x4212, \
   { 0xba, 0x3f, 0xfe, 0xac, 0xda, 0x4b, 0x92, 0x9e } }
 
 class nsIContentSink;
 class nsIRequestObserver;
 class nsString;
 class nsIURI;
 class nsIChannel;
-namespace mozilla {
-class Encoding;
-}
 
 enum eParserCommands {
   eViewNormal,
   eViewSource,
   eViewFragment,
   eViewErrors
 };
 
@@ -62,19 +58,16 @@ enum eStreamState {eNone,eOnStart,eOnDat
  *
  * Please DO NOT #include this file in comm-central code, in your XULRunner
  * app or binary extensions.
  *
  * Please DO NOT #include this into new files even inside Gecko. It is more
  * likely than not that #including this header is the wrong thing to do.
  */
 class nsIParser : public nsParserBase {
-  protected:
-    using Encoding = mozilla::Encoding;
-    template <typename T> using NotNull = mozilla::NotNull<T>;
   public:
 
     NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPARSER_IID)
 
     /**
      * Select given content sink into parser for parser output
      * @update	gess5/11/98
      * @param   aSink is the new sink to be used by parser
@@ -107,18 +100,18 @@ class nsIParser : public nsParserBase {
      *  Call this method once you've created a parser, and want to instruct it
      *  about what charset to load
      *  
      *  @update  ftang 4/23/99
      *  @param   aCharset- the charest of a document
      *  @param   aCharsetSource- the soure of the chares
      *  @return	 nada
      */
-    virtual void SetDocumentCharset(NotNull<const Encoding*> aCharset,
-                                    int32_t aSource) = 0;
+    NS_IMETHOD_(void) SetDocumentCharset(const nsACString& aCharset, int32_t aSource)=0;
+    NS_IMETHOD_(void) GetDocumentCharset(nsACString& oCharset, int32_t& oSource)=0;
 
     /** 
      * Get the channel associated with this parser
      * @update harishd,gagan 07/17/01
      * @param aChannel out param that will contain the result
      * @return NS_OK if successful
      */
     NS_IMETHOD GetChannel(nsIChannel** aChannel) override = 0;
--- a/parser/htmlparser/nsParser.cpp
+++ b/parser/htmlparser/nsParser.cpp
@@ -121,17 +121,16 @@ public:
 };
 
 //-------------- End ParseContinue Event Definition ------------------------
 
 /**
  *  default constructor
  */
 nsParser::nsParser()
-  : mCharset(WINDOWS_1252_ENCODING)
 {
   Initialize(true);
 }
 
 nsParser::~nsParser()
 {
   Cleanup();
 }
@@ -146,17 +145,17 @@ nsParser::Initialize(bool aConstructor)
   else {
     // nsCOMPtrs
     mObserver = nullptr;
     mUnusedInput.Truncate();
   }
 
   mContinueEvent = nullptr;
   mCharsetSource = kCharsetUninitialized;
-  mCharset = WINDOWS_1252_ENCODING;
+  mCharset.AssignLiteral("windows-1252");
   mInternalState = NS_OK;
   mStreamStatus = NS_OK;
   mCommand = eViewNormal;
   mBlocked = 0;
   mFlags = NS_PARSER_FLAG_OBSERVERS_ENABLED |
            NS_PARSER_FLAG_CAN_TOKENIZE;
 
   mProcessingNetworkData = false;
@@ -279,29 +278,28 @@ nsParser::SetCommand(eParserCommands aPa
 
 /**
  *  Call this method once you've created a parser, and want to instruct it
  *  about what charset to load
  *
  *  @param   aCharset- the charset of a document
  *  @param   aCharsetSource- the source of the charset
  */
-void
-nsParser::SetDocumentCharset(NotNull<const Encoding*> aCharset,
-                             int32_t aCharsetSource)
+NS_IMETHODIMP_(void)
+nsParser::SetDocumentCharset(const nsACString& aCharset, int32_t aCharsetSource)
 {
   mCharset = aCharset;
   mCharsetSource = aCharsetSource;
   if (mParserContext && mParserContext->mScanner) {
      mParserContext->mScanner->SetDocumentCharset(aCharset, aCharsetSource);
   }
 }
 
 void
-nsParser::SetSinkCharset(NotNull<const Encoding*> aCharset)
+nsParser::SetSinkCharset(nsACString& aCharset)
 {
   if (mSink) {
     mSink->SetDocumentCharset(aCharset);
   }
 }
 
 /**
  *  This method gets called in order to set the content
@@ -1328,37 +1326,38 @@ ParserWriteFunc(nsIInputStream* in,
 
   if (!pws) {
     return NS_ERROR_FAILURE;
   }
 
   if (pws->mNeedCharsetCheck) {
     pws->mNeedCharsetCheck = false;
     int32_t source;
-    auto preferred = pws->mParser->GetDocumentCharset(source);
+    nsAutoCString preferred;
+    pws->mParser->GetDocumentCharset(preferred, source);
 
     // This code was bogus when I found it. It expects the BOM or the XML
     // declaration to be entirely in the first network buffer. -- hsivonen
     const Encoding* encoding;
     size_t bomLength;
     Tie(encoding, bomLength) = Encoding::ForBOM(MakeSpan(buf, count));
     Unused << bomLength;
     if (encoding) {
       // The decoder will swallow the BOM. The UTF-16 will re-sniff for
       // endianness. The value of preferred is now "UTF-8", "UTF-16LE"
       // or "UTF-16BE".
-      preferred = WrapNotNull(encoding);
+      encoding->Name(preferred);
       source = kCharsetFromByteOrderMark;
     } else if (source < kCharsetFromChannel) {
       nsAutoCString declCharset;
 
       if (ExtractCharsetFromXmlDeclaration(buf, count, declCharset)) {
         encoding = Encoding::ForLabel(declCharset);
         if (encoding) {
-          preferred = WrapNotNull(encoding);
+          encoding->Name(preferred);
           source = kCharsetFromMetaTag;
         }
       }
     }
 
     pws->mParser->SetDocumentCharset(preferred, source);
     pws->mParser->SetSinkCharset(preferred);
 
--- a/parser/htmlparser/nsParser.h
+++ b/parser/htmlparser/nsParser.h
@@ -124,23 +124,22 @@ class nsParser final : public nsIParser,
      *  Call this method once you've created a parser, and want to instruct it
      *  about what charset to load
      *  
      *  @update  ftang 4/23/99
      *  @param   aCharset- the charset of a document
      *  @param   aCharsetSource- the source of the charset
      *  @return	 nada
      */
-    virtual void SetDocumentCharset(NotNull<const Encoding*> aCharset,
-                                    int32_t aSource) override;
+    NS_IMETHOD_(void) SetDocumentCharset(const nsACString& aCharset, int32_t aSource) override;
 
-    NotNull<const Encoding*> GetDocumentCharset(int32_t& aSource)
+    NS_IMETHOD_(void) GetDocumentCharset(nsACString& aCharset, int32_t& aSource) override
     {
+         aCharset = mCharset;
          aSource = mCharsetSource;
-         return mCharset;
     }
 
     /**
      * Cause parser to parse input from given URL 
      * @update	gess5/11/98
      * @param   aURL is a descriptor for source document
      * @param   aListener is a listener to forward notifications to
      * @return  TRUE if all went well -- FALSE otherwise
@@ -237,17 +236,17 @@ class nsParser final : public nsIParser,
      */
     NS_IMETHOD GetDTD(nsIDTD** aDTD) override;
   
     /**
      * Get the nsIStreamListener for this parser
      */
     virtual nsIStreamListener* GetStreamListener() override;
 
-    void SetSinkCharset(NotNull<const Encoding*> aCharset);
+    void SetSinkCharset(nsACString& aCharset);
 
     /**
      *  Removes continue parsing events
      *  @update  kmcclusk 5/18/98
      */
 
     NS_IMETHOD CancelParsingEvents() override;
 
@@ -384,17 +383,17 @@ protected:
     nsresult            mInternalState;
     nsresult            mStreamStatus;
     int32_t             mCharsetSource;
     
     uint16_t            mFlags;
     uint32_t            mBlocked;
 
     nsString            mUnusedInput;
-    NotNull<const Encoding*> mCharset;
+    nsCString           mCharset;
     nsCString           mCommandStr;
 
     bool                mProcessingNetworkData;
     bool                mIsAboutBlank;
 };
 
 #endif 
 
--- a/parser/htmlparser/nsScanner.cpp
+++ b/parser/htmlparser/nsScanner.cpp
@@ -88,37 +88,45 @@ nsScanner::nsScanner(nsString& aFilename
   mMarkPosition = mCurrentPosition;
   mEndPosition = mCurrentPosition;
 
   mIncremental = true;
 
   mUnicodeDecoder = nullptr;
   mCharsetSource = kCharsetUninitialized;
   // XML defaults to UTF-8 and about:blank is UTF-8, too.
-  SetDocumentCharset(UTF_8_ENCODING, kCharsetFromDocTypeDefault);
+  SetDocumentCharset(NS_LITERAL_CSTRING("UTF-8"), kCharsetFromDocTypeDefault);
 }
 
-nsresult nsScanner::SetDocumentCharset(NotNull<const Encoding*> aEncoding,
-                                       int32_t aSource)
+nsresult nsScanner::SetDocumentCharset(const nsACString& aCharset , int32_t aSource)
 {
   if (aSource < mCharsetSource) // priority is lower than the current one
     return NS_OK;
 
   mCharsetSource = aSource;
+
+  const Encoding* encoding;
+  if (aCharset.EqualsLiteral("replacement")) {
+    encoding = REPLACEMENT_ENCODING;
+  } else {
+    encoding = Encoding::ForLabel(aCharset);
+    MOZ_ASSERT(encoding, "Should never call with a bogus aCharset.");
+  }
+
   nsCString charsetName;
-  aEncoding->Name(charsetName);
+  encoding->Name(charsetName);
   if (!mCharset.IsEmpty() && charsetName.Equals(mCharset)) {
     return NS_OK; // no difference, don't change it
   }
 
   // different, need to change it
 
   mCharset.Assign(charsetName);
 
-  mUnicodeDecoder = aEncoding->NewDecoderWithBOMRemoval();
+  mUnicodeDecoder = encoding->NewDecoderWithBOMRemoval();
 
   return NS_OK;
 }
 
 
 /**
  *  default destructor
  *  
--- a/parser/htmlparser/nsScanner.h
+++ b/parser/htmlparser/nsScanner.h
@@ -31,19 +31,17 @@ public:
   const char16_t *mChars;
   char16_t mFilter;
   explicit nsReadEndCondition(const char16_t* aTerminateChars);
 private:
   nsReadEndCondition(const nsReadEndCondition& aOther); // No copying
   void operator=(const nsReadEndCondition& aOther); // No assigning
 };
 
-class nsScanner final {
-      using Encoding = mozilla::Encoding;
-      template <typename T> using NotNull = mozilla::NotNull<T>;
+class nsScanner {
   public:
 
       /**
        *  Use this constructor for the XML fragment parsing case
        */
       explicit nsScanner(const nsAString& anHTMLString);
 
       /**
@@ -139,18 +137,17 @@ class nsScanner final {
       /**
        *  Use this setter to change the scanner's unicode decoder
        *
        *  @update  ftang 3/02/99
        *  @param   aCharset a normalized (alias resolved) charset name
        *  @param   aCharsetSource- where the charset info came from
        *  @return  
        */
-      nsresult SetDocumentCharset(NotNull<const Encoding*> aEncoding,
-                                  int32_t aSource);
+      nsresult SetDocumentCharset(const nsACString& aCharset, int32_t aSource);
 
       void BindSubstring(nsScannerSubstring& aSubstring, const nsScannerIterator& aStart, const nsScannerIterator& aEnd);
       void CurrentPosition(nsScannerIterator& aPosition);
       void EndReading(nsScannerIterator& aPosition);
       void SetPosition(nsScannerIterator& aPosition,
                        bool aTruncate = false);
 
       /**
--- a/parser/xml/nsSAXXMLReader.cpp
+++ b/parser/xml/nsSAXXMLReader.cpp
@@ -15,17 +15,16 @@
 #include "nsStreamUtils.h"
 #include "nsStringStream.h"
 #include "nsIScriptError.h"
 #include "nsSAXAttributes.h"
 #include "nsSAXLocator.h"
 #include "nsCharsetSource.h"
 
 using mozilla::Encoding;
-using mozilla::NotNull;
 
 #define XMLNS_URI "http://www.w3.org/2000/xmlns/"
 
 static NS_DEFINE_CID(kParserCID, NS_PARSER_CID);
 
 NS_IMPL_CYCLE_COLLECTION(nsSAXXMLReader,
                          mContentHandler,
                          mDTDHandler,
@@ -624,46 +623,46 @@ nsSAXXMLReader::InitParser(nsIRequestObs
 
   // setup the parser
   nsCOMPtr<nsIParser> parser = do_CreateInstance(kParserCID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   parser->SetContentSink(this);
 
   int32_t charsetSource = kCharsetFromDocTypeDefault;
-  auto encoding = UTF_8_ENCODING;
-  TryChannelCharset(aChannel, charsetSource, encoding);
-  parser->SetDocumentCharset(encoding, charsetSource);
+  nsAutoCString charset(NS_LITERAL_CSTRING("UTF-8"));
+  TryChannelCharset(aChannel, charsetSource, charset);
+  parser->SetDocumentCharset(charset, charsetSource);
 
   rv = parser->Parse(mBaseURI, aObserver);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mListener = do_QueryInterface(parser, &rv);
 
   return rv;
 }
 
 // from nsDocument.cpp
 bool
 nsSAXXMLReader::TryChannelCharset(nsIChannel *aChannel,
                                   int32_t& aCharsetSource,
-                                  NotNull<const Encoding*>& aEncoding)
+                                  nsACString& aCharset)
 {
   if (aCharsetSource >= kCharsetFromChannel)
     return true;
   
   if (aChannel) {
     nsAutoCString charsetVal;
     nsresult rv = aChannel->GetContentCharset(charsetVal);
     if (NS_SUCCEEDED(rv)) {
       const Encoding* preferred = Encoding::ForLabel(charsetVal);
       if (!preferred)
         return false;
 
-      aEncoding = WrapNotNull(preferred);
+      preferred->Name(aCharset);
       aCharsetSource = kCharsetFromChannel;
       return true;
     }
   }
 
   return false;
 }
 
--- a/parser/xml/nsSAXXMLReader.h
+++ b/parser/xml/nsSAXXMLReader.h
@@ -14,17 +14,16 @@
 #include "nsISAXXMLReader.h"
 #include "nsISAXContentHandler.h"
 #include "nsISAXDTDHandler.h"
 #include "nsISAXErrorHandler.h"
 #include "nsISAXLexicalHandler.h"
 #include "nsIMozSAXXMLDeclarationHandler.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/NotNull.h"
 
 #define NS_SAXXMLREADER_CONTRACTID "@mozilla.org/saxparser/xmlreader;1"
 #define NS_SAXXMLREADER_CID  \
 { 0xab1da296, 0x6125, 0x40ba, \
 { 0x96, 0xd0, 0x47, 0xa8, 0x28, 0x2a, 0xe3, 0xdb} }
 
 class nsSAXXMLReader final : public nsISAXXMLReader,
                              public nsIExtendedExpatSink,
@@ -60,18 +59,19 @@ public:
   {
     return NS_OK;
   }
   
   virtual void FlushPendingNotifications(mozilla::FlushType aType) override
   {
   }
   
-  virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override
+  NS_IMETHOD SetDocumentCharset(nsACString& aCharset) override
   {
+    return NS_OK;
   }
   
   virtual nsISupports *GetTarget() override
   {
     return nullptr;
   }
 
 private:
@@ -82,18 +82,18 @@ private:
   nsCOMPtr<nsISAXErrorHandler> mErrorHandler;
   nsCOMPtr<nsISAXLexicalHandler> mLexicalHandler;
   nsCOMPtr<nsIMozSAXXMLDeclarationHandler> mDeclarationHandler;
   nsCOMPtr<nsIURI> mBaseURI;
   nsCOMPtr<nsIStreamListener> mListener;
   nsCOMPtr<nsIRequestObserver> mParserObserver;
   bool mIsAsyncParse;
   static bool TryChannelCharset(nsIChannel *aChannel,
-                                int32_t& aCharsetSource,
-                                NotNull<const Encoding*>& aEncoding);
+                                  int32_t& aCharsetSource,
+                                  nsACString& aCharset);
   nsresult EnsureBaseURI();
   nsresult InitParser(nsIRequestObserver *aListener, nsIChannel *aChannel);
   nsresult SplitExpatName(const char16_t *aExpatName,
                           nsString &aURI,
                           nsString &aLocalName,
                           nsString &aQName);
   nsString mPublicId;
   nsString mSystemId;
--- a/rdf/base/nsRDFContentSink.cpp
+++ b/rdf/base/nsRDFContentSink.cpp
@@ -101,18 +101,17 @@ public:
     // nsIContentSink
     NS_IMETHOD WillParse(void) override;
     NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override;
     NS_IMETHOD DidBuildModel(bool aTerminated) override;
     NS_IMETHOD WillInterrupt(void) override;
     NS_IMETHOD WillResume(void) override;
     NS_IMETHOD SetParser(nsParserBase* aParser) override;
     virtual void FlushPendingNotifications(mozilla::FlushType aType) override { }
-    virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding)
-      override { }
+    NS_IMETHOD SetDocumentCharset(nsACString& aCharset) override { return NS_OK; }
     virtual nsISupports *GetTarget() override { return nullptr; }
 
     // nsIRDFContentSink
     NS_IMETHOD Init(nsIURI* aURL) override;
     NS_IMETHOD SetDataSource(nsIRDFDataSource* aDataSource) override;
     NS_IMETHOD GetDataSource(nsIRDFDataSource*& aDataSource) override;
 
     // pseudo constants
--- a/rdf/base/nsRDFXMLParser.cpp
+++ b/rdf/base/nsRDFXMLParser.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 4; 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 "nsRDFXMLParser.h"
 
-#include "mozilla/Encoding.h"
 #include "nsIComponentManager.h"
 #include "nsIParser.h"
 #include "nsCharsetSource.h"
 #include "nsIRDFContentSink.h"
 #include "nsParserCIID.h"
 #include "nsStringStream.h"
 #include "nsNetUtil.h"
 #include "NullPrincipal.h"
@@ -61,17 +60,17 @@ nsRDFXMLParser::ParseAsync(nsIRDFDataSou
     // We set the content sink's data source directly to our in-memory
     // store. This allows the initial content to be generated "directly".
     rv = sink->SetDataSource(aSink);
     if (NS_FAILED(rv)) return rv;
 
     nsCOMPtr<nsIParser> parser = do_CreateInstance(kParserCID, &rv);
     if (NS_FAILED(rv)) return rv;
 
-    parser->SetDocumentCharset(UTF_8_ENCODING,
+    parser->SetDocumentCharset(NS_LITERAL_CSTRING("UTF-8"),
                                kCharsetFromDocTypeDefault);
     parser->SetContentSink(sink);
 
     rv = parser->Parse(aBaseURI);
     if (NS_FAILED(rv)) return rv;
 
     return CallQueryInterface(parser, aResult);
 }
@@ -92,17 +91,17 @@ nsRDFXMLParser::ParseString(nsIRDFDataSo
     // We set the content sink's data source directly to our in-memory
     // store. This allows the initial content to be generated "directly".
     rv = sink->SetDataSource(aSink);
     if (NS_FAILED(rv)) return rv;
 
     nsCOMPtr<nsIParser> parser = do_CreateInstance(kParserCID, &rv);
     if (NS_FAILED(rv)) return rv;
 
-    parser->SetDocumentCharset(UTF_8_ENCODING,
+    parser->SetDocumentCharset(NS_LITERAL_CSTRING("UTF-8"),
                                kCharsetFromOtherComponent);
     parser->SetContentSink(sink);
 
     rv = parser->Parse(aBaseURI);
     if (NS_FAILED(rv)) return rv;
 
     nsCOMPtr<nsIStreamListener> listener =
         do_QueryInterface(parser);