Bug 871161 - Stop inheriting charset where other browsers do not inherit it. r=bzbarsky.
authorHenri Sivonen <hsivonen@hsivonen.fi>
Wed, 16 Oct 2013 04:46:10 +0300
changeset 165715 2ba9f3b24b8a54fd3a76a8aa91b6fc56d395c755
parent 165714 97e7c6a2b6a545835850cd4a13807bc443e15f7f
child 165716 408a5a43fc6e58041b40ec3402a85acbdedb4069
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs871161
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 871161 - Stop inheriting charset where other browsers do not inherit it. r=bzbarsky.
browser/base/content/browser.js
content/html/document/src/MediaDocument.cpp
content/html/document/src/nsHTMLContentSink.cpp
content/html/document/src/nsHTMLDocument.cpp
content/html/document/src/nsHTMLDocument.h
content/html/document/test/Makefile.in
content/html/document/test/file_bug871161-1.html
content/html/document/test/file_bug871161-2.html
content/html/document/test/test_bug871161.html
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/nsIDocShell.idl
docshell/base/nsIMarkupDocumentViewer.idl
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
layout/base/nsDocumentViewer.cpp
parser/html/nsHtml5TreeOpExecutor.cpp
parser/nsCharsetSource.h
toolkit/components/viewsource/content/viewSource.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -773,28 +773,16 @@ var gBrowserInit = {
           .getInterface(nsIWebNavigation)
           .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
           .QueryInterface(Ci.nsIInterfaceRequestor)
           .getInterface(Ci.nsIXULWindow)
           .XULBrowserWindow = window.XULBrowserWindow;
     window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow =
       new nsBrowserAccess();
 
-    // set default character set if provided
-    // window.arguments[1]: character set (string)
-    if ("arguments" in window && window.arguments.length > 1 && window.arguments[1]) {
-      if (window.arguments[1].startsWith("charset=")) {
-        var arrayArgComponents = window.arguments[1].split("=");
-        if (arrayArgComponents) {
-          //we should "inherit" the charset menu setting in a new window
-          getMarkupDocumentViewer().defaultCharacterSet = arrayArgComponents[1];
-        }
-      }
-    }
-
     // Manually hook up session and global history for the first browser
     // so that we don't have to load global history before bringing up a
     // window.
     // Wire up session and global history before any possible
     // progress notifications for back/forward button updating
     gBrowser.webNavigation.sessionHistory = Cc["@mozilla.org/browser/shistory;1"].
                                             createInstance(Ci.nsISHistory);
     Services.obs.addObserver(gBrowser.browsers[0], "browser:purge-session-history", false);
--- a/content/html/document/src/MediaDocument.cpp
+++ b/content/html/document/src/MediaDocument.cpp
@@ -16,16 +16,17 @@
 #include "nsIMarkupDocumentViewer.h"
 #include "nsIDocShell.h"
 #include "nsCharsetSource.h" // kCharsetFrom* macro definition
 #include "nsNodeInfoManager.h"
 #include "nsContentUtils.h"
 #include "nsDocElementCreatedNotificationRunner.h"
 #include "mozilla/Services.h"
 #include "nsServiceManagerUtils.h"
+#include "nsIPrincipal.h"
 
 namespace mozilla {
 namespace dom {
 
 MediaDocumentStreamListener::MediaDocumentStreamListener(MediaDocument *aDocument)
 {
   mDocument = aDocument;
 }
@@ -145,55 +146,39 @@ MediaDocument::StartDocumentLoad(const c
 
   // We try to set the charset of the current document to that of the 
   // 'genuine' (as opposed to an intervening 'chrome') parent document 
   // that may be in a different window/tab. Even if we fail here,
   // we just return NS_OK because another attempt is made in 
   // |UpdateTitleAndCharset| and the worst thing possible is a mangled 
   // filename in the titlebar and the file picker.
 
-  // When this document is opened in the window/tab of the referring 
-  // document (by a simple link-clicking), |prevDocCharacterSet| contains 
-  // the charset of the referring document. On the other hand, if the
-  // document is opened in a new window, it is |defaultCharacterSet| of |muCV| 
-  // where the charset of our interest is stored. In case of openining 
-  // in a new tab, we get the charset from the docShell. Note that we 
+  // Note that we
   // exclude UTF-8 as 'invalid' because UTF-8 is likely to be the charset 
   // of a chrome document that has nothing to do with the actual content 
   // whose charset we want to know. Even if "the actual content" is indeed 
   // 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); 
 
   nsAutoCString charset;
+  int32_t source;
+  nsCOMPtr<nsIPrincipal> principal;
   // opening in a new tab
-  docShell->GetParentCharset(charset);
-
-  if (charset.IsEmpty() || charset.Equals("UTF-8")) {
-    nsCOMPtr<nsIContentViewer> cv;
-    docShell->GetContentViewer(getter_AddRefs(cv));
+  docShell->GetParentCharset(charset, &source, getter_AddRefs(principal));
 
-    // not being able to set the charset is not critical.
-    NS_ENSURE_TRUE(cv, NS_OK); 
-    nsCOMPtr<nsIMarkupDocumentViewer> muCV = do_QueryInterface(cv);
-    if (muCV) {
-      muCV->GetPrevDocCharacterSet(charset);   // opening in the same window/tab
-      if (charset.Equals("UTF-8") || charset.IsEmpty()) {
-        muCV->GetDefaultCharacterSet(charset); // opening in a new window
-      }
-    } 
-  }
-
-  if (!charset.IsEmpty() && !charset.Equals("UTF-8")) {
+  if (!charset.IsEmpty() &&
+      !charset.Equals("UTF-8") &&
+      NodePrincipal()->Equals(principal)) {
+    SetDocumentCharacterSetSource(source);
     SetDocumentCharacterSet(charset);
-    mCharacterSetSource = kCharsetFromUserDefault;
   }
 
   return NS_OK;
 }
 
 void
 MediaDocument::BecomeInteractive()
 {
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -1129,57 +1129,18 @@ HTMLContentSink::FlushTags()
   }
   
   return mCurrentContext ? mCurrentContext->FlushTags() : NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLContentSink::SetDocumentCharset(nsACString& aCharset)
 {
-  if (mDocShell) {
-    // the following logic to get muCV is copied from
-    // nsHTMLDocument::StartDocumentLoad
-    // We need to call muCV->SetPrevDocCharacterSet here in case
-    // the charset is detected by parser DetectMetaTag
-    nsCOMPtr<nsIMarkupDocumentViewer> muCV;
-    nsCOMPtr<nsIContentViewer> cv;
-    mDocShell->GetContentViewer(getter_AddRefs(cv));
-    if (cv) {
-       muCV = do_QueryInterface(cv);
-    } else {
-      // in this block of code, if we get an error result, we return
-      // it but if we get a null pointer, that's perfectly legal for
-      // parent and parentContentViewer
-
-      NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
-
-      nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
-      mDocShell->GetSameTypeParent(getter_AddRefs(parentAsItem));
-
-      nsCOMPtr<nsIDocShell> parent(do_QueryInterface(parentAsItem));
-      if (parent) {
-        nsCOMPtr<nsIContentViewer> parentContentViewer;
-        nsresult rv =
-          parent->GetContentViewer(getter_AddRefs(parentContentViewer));
-        if (NS_SUCCEEDED(rv) && parentContentViewer) {
-          muCV = do_QueryInterface(parentContentViewer);
-        }
-      }
-    }
-
-    if (muCV) {
-      muCV->SetPrevDocCharacterSet(aCharset);
-    }
-  }
-
-  if (mDocument) {
-    mDocument->SetDocumentCharacterSet(aCharset);
-  }
-
-  return NS_OK;
+  MOZ_ASSUME_UNREACHABLE("<meta charset> case doesn't occur with about:blank");
+  return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsISupports *
 HTMLContentSink::GetTarget()
 {
   return mDocument;
 }
 
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -390,88 +390,56 @@ nsHTMLDocument::TryCacheCharset(nsICachi
       !cachedCharset.IsEmpty() &&
       EncodingUtils::IsAsciiCompatible(cachedCharset))
   {
     aCharset = cachedCharset;
     aCharsetSource = kCharsetFromCache;
   }
 }
 
-static bool
-CheckSameOrigin(nsINode* aNode1, nsINode* aNode2)
-{
-  NS_PRECONDITION(aNode1, "Null node?");
-  NS_PRECONDITION(aNode2, "Null node?");
-
-  bool equal;
-  return
-    NS_SUCCEEDED(aNode1->NodePrincipal()->
-                   Equals(aNode2->NodePrincipal(), &equal)) &&
-    equal;
-}
-
 void
 nsHTMLDocument::TryParentCharset(nsIDocShell*  aDocShell,
-                                 nsIDocument* aParentDocument,
                                  int32_t& aCharsetSource,
                                  nsACString& aCharset)
 {
   if (!aDocShell) {
     return;
   }
   if (aCharsetSource >= kCharsetFromParentForced) {
     return;
   }
 
   int32_t parentSource;
   nsAutoCString parentCharset;
-  aDocShell->GetParentCharset(parentCharset);
+  nsCOMPtr<nsIPrincipal> parentPrincipal;
+  aDocShell->GetParentCharset(parentCharset,
+                              &parentSource,
+                              getter_AddRefs(parentPrincipal));
   if (parentCharset.IsEmpty()) {
     return;
   }
-  aDocShell->GetParentCharsetSource(&parentSource);
   if (kCharsetFromParentForced == parentSource ||
       kCharsetFromUserForced == parentSource) {
     if (WillIgnoreCharsetOverride() ||
         !EncodingUtils::IsAsciiCompatible(aCharset) || // if channel said UTF-16
         !EncodingUtils::IsAsciiCompatible(parentCharset)) {
       return;
     }
     aCharset.Assign(parentCharset);
     aCharsetSource = kCharsetFromParentForced;
     return;
   }
 
-  if (aCharsetSource >= kCharsetFromHintPrevDoc) {
-    return;
-  }
-
-  if (kCharsetFromHintPrevDoc == parentSource) {
-    // Make sure that's OK
-    if (!aParentDocument ||
-        !CheckSameOrigin(this, aParentDocument) ||
-        !EncodingUtils::IsAsciiCompatible(parentCharset)) {
-      return;
-    }
-
-    // if parent is posted doc, set this prevent autodetections
-    // I'm not sure this makes much sense... but whatever.
-    aCharset.Assign(parentCharset);
-    aCharsetSource = kCharsetFromHintPrevDoc;
-    return;
-  }
-
   if (aCharsetSource >= kCharsetFromParentFrame) {
     return;
   }
 
   if (kCharsetFromCache <= parentSource) {
     // Make sure that's OK
-    if (!aParentDocument ||
-        !CheckSameOrigin(this, aParentDocument) ||
+    if (!NodePrincipal()->Equals(parentPrincipal) ||
         !EncodingUtils::IsAsciiCompatible(parentCharset)) {
       return;
     }
 
     aCharset.Assign(parentCharset);
     aCharsetSource = kCharsetFromParentFrame;
   }
 }
@@ -495,35 +463,16 @@ nsHTMLDocument::TryWeakDocTypeDefault(in
   } else {
     aCharset.AssignLiteral("windows-1252");
   }
   aCharsetSource = kCharsetFromWeakDocTypeDefault;
   return;
 }
 
 void
-nsHTMLDocument::TryDefaultCharset( nsIMarkupDocumentViewer* aMarkupDV,
-                                   int32_t& aCharsetSource,
-                                   nsACString& aCharset)
-{
-  if(kCharsetFromUserDefault <= aCharsetSource)
-    return;
-
-  nsAutoCString defaultCharsetFromDocShell;
-  if (aMarkupDV) {
-    nsresult rv =
-      aMarkupDV->GetDefaultCharacterSet(defaultCharsetFromDocShell);
-    if(NS_SUCCEEDED(rv) && EncodingUtils::IsAsciiCompatible(defaultCharsetFromDocShell)) {
-      aCharset = defaultCharsetFromDocShell;
-      aCharsetSource = kCharsetFromUserDefault;
-    }
-  }
-}
-
-void
 nsHTMLDocument::SetDocumentCharacterSet(const nsACString& aCharSetID)
 {
   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) {
     wyciwygChannel->SetCharsetAndSource(GetDocumentCharacterSetSource(),
@@ -647,42 +596,31 @@ nsHTMLDocument::StartDocumentLoad(const 
   // and parentContentViewer
   nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
   nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
   if (docShell) {
     docShell->GetSameTypeParent(getter_AddRefs(parentAsItem));
   }
 
   nsCOMPtr<nsIDocShell> parent(do_QueryInterface(parentAsItem));
-  nsCOMPtr<nsIDocument> parentDocument;
   nsCOMPtr<nsIContentViewer> parentContentViewer;
   if (parent) {
     rv = parent->GetContentViewer(getter_AddRefs(parentContentViewer));
     NS_ENSURE_SUCCESS(rv, rv);
-    if (parentContentViewer) {
-      parentDocument = parentContentViewer->GetDocument();
-    }
   }
 
-  //
-  // The following logic is mirrored in nsWebShell::Embed!
-  //
   nsCOMPtr<nsIMarkupDocumentViewer> muCV;
-  bool muCVIsParent = false;
   nsCOMPtr<nsIContentViewer> cv;
   if (docShell) {
     docShell->GetContentViewer(getter_AddRefs(cv));
   }
   if (cv) {
      muCV = do_QueryInterface(cv);
   } else {
     muCV = do_QueryInterface(parentContentViewer);
-    if (muCV) {
-      muCVIsParent = true;
-    }
   }
 
   nsAutoCString urlSpec;
   uri->GetSpec(urlSpec);
 #ifdef DEBUG_charset
   printf("Determining charset for %s\n", urlSpec.get());
 #endif
 
@@ -734,45 +672,24 @@ nsHTMLDocument::StartDocumentLoad(const 
       // interpretation as ASCII and the user can be lured to using the
       // charset menu.
       TryChannelCharset(aChannel, charsetSource, charset, executor);
     }
 
     TryUserForcedCharset(muCV, docShell, charsetSource, charset);
 
     TryHintCharset(muCV, charsetSource, charset); // XXX mailnews-only
-    TryParentCharset(docShell, parentDocument, charsetSource, charset);
+    TryParentCharset(docShell, charsetSource, charset);
 
     if (cachingChan && !urlSpec.IsEmpty()) {
       TryCacheCharset(cachingChan, charsetSource, charset);
     }
 
-    TryDefaultCharset(muCV, charsetSource, charset);
-
     TryWeakDocTypeDefault(charsetSource, charset);
 
-    bool isPostPage = false;
-    // check if current doc is from POST command
-    nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aChannel));
-    if (httpChannel) {
-      nsAutoCString methodStr;
-      rv = httpChannel->GetRequestMethod(methodStr);
-      isPostPage = (NS_SUCCEEDED(rv) &&
-                    methodStr.EqualsLiteral("POST"));
-    }
-
-    if (isPostPage && muCV && kCharsetFromHintPrevDoc > charsetSource) {
-      nsAutoCString requestCharset;
-      muCV->GetPrevDocCharacterSet(requestCharset);
-      if (!requestCharset.IsEmpty()) {
-        charsetSource = kCharsetFromHintPrevDoc;
-        charset = requestCharset;
-      }
-    }
-
     if (wyciwygChannel) {
       // We know for sure that the parser needs to be using UTF16.
       parserCharset = "UTF-16";
       parserCharsetSource = charsetSource < kCharsetFromChannel ?
         kCharsetFromChannel : charsetSource;
         
       nsAutoCString cachedCharset;
       int32_t cachedSource;
@@ -791,21 +708,16 @@ nsHTMLDocument::StartDocumentLoad(const 
       parserCharset = charset;
       parserCharsetSource = charsetSource;
     }
   }
 
   SetDocumentCharacterSetSource(charsetSource);
   SetDocumentCharacterSet(charset);
 
-  // set doc charset to muCV for next document.
-  // Don't propagate this back up to the parent document if we have one.
-  if (muCV && !muCVIsParent)
-    muCV->SetPrevDocCharacterSet(charset);
-
   if (cachingChan) {
     NS_ASSERTION(charset == parserCharset,
                  "How did those end up different here?  wyciwyg channels are "
                  "not nsICachingChannel");
     rv = cachingChan->SetCacheTokenCachedCharset(charset);
     NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "cannot SetMetaDataElement");
     rv = NS_OK; // don't propagate error
   }
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -306,25 +306,20 @@ protected:
                              nsACString& aCharset);
   void TryUserForcedCharset(nsIMarkupDocumentViewer* aMarkupDV,
                             nsIDocShell*  aDocShell,
                             int32_t& aCharsetSource,
                             nsACString& aCharset);
   static void TryCacheCharset(nsICachingChannel* aCachingChannel,
                                 int32_t& aCharsetSource,
                                 nsACString& aCharset);
-  // aParentDocument could be null.
   void TryParentCharset(nsIDocShell*  aDocShell,
-                        nsIDocument* aParentDocument,
                         int32_t& charsetSource, nsACString& aCharset);
   static void TryWeakDocTypeDefault(int32_t& aCharsetSource,
                                     nsACString& aCharset);
-  static void TryDefaultCharset(nsIMarkupDocumentViewer* aMarkupDV,
-                                int32_t& aCharsetSource,
-                                nsACString& aCharset);
 
   // Override so we can munge the charset on our wyciwyg channel as needed.
   virtual void SetDocumentCharacterSet(const nsACString& aCharSetID) MOZ_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.
--- a/content/html/document/test/Makefile.in
+++ b/content/html/document/test/Makefile.in
@@ -61,10 +61,13 @@ MOCHITEST_FILES = 	test_bug1682.html \
 		bug499092.html \
 		test_bug512367.html \
 		test_bug677495.html \
 		test_bug677495-1.html \
 		test_bug741266.html \
 		test_non-ascii-cookie.html \
 		test_non-ascii-cookie.html^headers^ \
 		test_bug765780.html \
+		test_bug871161.html \
+		file_bug871161-1.html \
+		file_bug871161-2.html \
 		$(NULL)
 
new file mode 100644
--- /dev/null
+++ b/content/html/document/test/file_bug871161-1.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=windows-1251>
+<title>Page with non-default charset</title>
+<script>
+function run() {
+  document.forms[0].submit();
+}
+</script>
+</head>
+<body onload="run();">
+<form method=post action="http://example.org/tests/content/html/document/test/file_bug871161-2.html"></form>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/content/html/document/test/file_bug871161-2.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Page without declared charset</title>
+<script>
+function done() {
+  window.opener.postMessage(document.characterSet, "*");
+}
+</script>
+</head>
+<body onload="done();">
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/content/html/document/test/test_bug871161.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=871161
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 871161</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+  /** Test for Bug 871161 **/
+  SimpleTest.waitForExplicitFinish();
+
+  window.onmessage = function(e) {
+    is(e.data, "windows-1252", "Wrong charset");
+    e.source.close();
+    SimpleTest.finish();
+  }
+
+  function run() {
+    window.open("file_bug871161-1.html");
+  }
+
+  </script>
+</head>
+<body onload="run();">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=871161">Mozilla Bug 871161</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1854,30 +1854,25 @@ nsDocShell::SetCurrentURI(nsIURI *aURI, 
 
     if (aFireOnLocationChange) {
         FireOnLocationChange(this, aRequest, aURI, aLocationFlags);
     }
     return !aFireOnLocationChange;
 }
 
 NS_IMETHODIMP
-nsDocShell::GetCharset(char** aCharset)
-{
-    NS_ENSURE_ARG_POINTER(aCharset);
-    *aCharset = nullptr; 
+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);
-    *aCharset = ToNewCString(doc->GetDocumentCharacterSet());
-    if (!*aCharset) {
-        return NS_ERROR_OUT_OF_MEMORY;
-    }
-
+    aCharset = doc->GetDocumentCharacterSet();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GatherCharsetMenuTelemetry()
 {
   nsCOMPtr<nsIContentViewer> viewer;
   GetContentViewer(getter_AddRefs(viewer));
@@ -1896,17 +1891,16 @@ nsDocShell::GatherCharsetMenuTelemetry()
   nsIURI* url = doc->GetOriginalURI();
   if (url) {
     url->SchemeIs("file", &isFileURL);
   }
 
   int32_t charsetSource = doc->GetDocumentCharacterSetSource();
   switch (charsetSource) {
     case kCharsetFromWeakDocTypeDefault:
-    case kCharsetFromUserDefault:
     case kCharsetFromDocTypeDefault:
     case kCharsetFromCache:
     case kCharsetFromParentFrame:
     case kCharsetFromHintPrevDoc:
       // Changing charset on an unlabeled doc.
       if (isFileURL) {
         Telemetry::Accumulate(Telemetry::CHARSET_OVERRIDE_SITUATION, 0);
       } else {
@@ -1940,71 +1934,54 @@ nsDocShell::GatherCharsetMenuTelemetry()
       // Bug. This isn't supposed to happen.
       Telemetry::Accumulate(Telemetry::CHARSET_OVERRIDE_SITUATION, 6);
       break;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocShell::SetCharset(const char* aCharset)
-{
-    // set the default charset
-    nsCOMPtr<nsIContentViewer> viewer;
-    GetContentViewer(getter_AddRefs(viewer));
-    if (viewer) {
-      nsCOMPtr<nsIMarkupDocumentViewer> muDV(do_QueryInterface(viewer));
-      if (muDV) {
-        nsCString charset(aCharset);
-        NS_ENSURE_SUCCESS(muDV->SetDefaultCharacterSet(charset),
-                          NS_ERROR_FAILURE);
-      }
-    }
-
+nsDocShell::SetCharset(const nsACString& aCharset)
+{
     // set the charset override
-    nsCString charset(aCharset);
-    SetForcedCharset(charset);
+    SetForcedCharset(aCharset);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP nsDocShell::SetForcedCharset(const nsACString& aCharset)
 {
   mForcedCharset = aCharset;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsDocShell::GetForcedCharset(nsACString& aResult)
 {
   aResult = mForcedCharset;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsDocShell::SetParentCharset(const nsACString& aCharset)
+void
+nsDocShell::SetParentCharset(const nsACString& aCharset,
+                             int32_t aCharsetSource,
+                             nsIPrincipal* aPrincipal)
 {
   mParentCharset = aCharset;
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsDocShell::GetParentCharset(nsACString& aResult)
-{
-  aResult = mParentCharset;
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsDocShell::SetParentCharsetSource(int32_t aCharsetSource)
-{
   mParentCharsetSource = aCharsetSource;
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsDocShell::GetParentCharsetSource(int32_t * aParentCharsetSource)
-{
-  *aParentCharsetSource = mParentCharsetSource;
-  return NS_OK;
+  mParentCharsetPrincipal = aPrincipal;
+}
+
+void
+nsDocShell::GetParentCharset(nsACString& aCharset,
+                             int32_t* aCharsetSource,
+                             nsIPrincipal** aPrincipal)
+{
+  aCharset = mParentCharset;
+  *aCharsetSource = mParentCharsetSource;
+  NS_IF_ADDREF(*aPrincipal = mParentCharsetPrincipal);
 }
 
 NS_IMETHODIMP
 nsDocShell::GetChannelIsUnsafe(bool *aUnsafe)
 {
     *aUnsafe = false;
 
     nsIChannel* channel = GetCurrentDocChannel();
@@ -3567,42 +3544,36 @@ nsDocShell::AddChild(nsIDocShellTreeItem
         return NS_OK;
 
     // get the parent's current charset
     if (!mContentViewer)
         return NS_OK;
     nsIDocument* doc = mContentViewer->GetDocument();
     if (!doc)
         return NS_OK;
-    const nsACString &parentCS = doc->GetDocumentCharacterSet();
 
     bool isWyciwyg = false;
 
     if (mCurrentURI) {
         // Check if the url is wyciwyg
         mCurrentURI->SchemeIs("wyciwyg", &isWyciwyg);      
     }
 
     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.
 
-        // set the child's parentCharset
-        res = childAsDocShell->SetParentCharset(parentCS);
-        if (NS_FAILED(res))
-            return NS_OK;
-
+        const nsACString &parentCS = doc->GetDocumentCharacterSet();
         int32_t charsetSource = doc->GetDocumentCharacterSetSource();
-
         // set the child's parentCharset
-        res = childAsDocShell->SetParentCharsetSource(charsetSource);
-        if (NS_FAILED(res))
-            return NS_OK;
+        childAsDocShell->SetParentCharset(parentCS,
+                                          charsetSource,
+                                          doc->NodePrincipal());
     }
 
     // printf("### 1 >>> Adding child. Parent CS = %s. ItemType = %d.\n", NS_LossyConvertUTF16toASCII(parentCS).get(), mItemType);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -8293,21 +8264,19 @@ nsDocShell::SetupNewViewer(nsIContentVie
     // Init settings
     DoGetPositionAndSize(&x, &y, &cx, &cy);
 
     nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
     NS_ENSURE_SUCCESS(GetSameTypeParent(getter_AddRefs(parentAsItem)),
                       NS_ERROR_FAILURE);
     nsCOMPtr<nsIDocShell> parent(do_QueryInterface(parentAsItem));
 
-    nsAutoCString defaultCharset;
     nsAutoCString forceCharset;
     nsAutoCString hintCharset;
     int32_t hintCharsetSource;
-    nsAutoCString prevDocCharset;
     int32_t minFontSize;
     float textZoom;
     float pageZoom;
     bool styleDisabled;
     // |newMUDV| also serves as a flag to set the data from the above vars
     nsCOMPtr<nsIMarkupDocumentViewer> newMUDV;
 
     if (mContentViewer || parent) {
@@ -8336,19 +8305,16 @@ nsDocShell::SetupNewViewer(nsIContentVie
         }
 
         if (oldMUDV) {
             nsresult rv;
 
             newMUDV = do_QueryInterface(aNewViewer,&rv);
             if (newMUDV) {
                 NS_ENSURE_SUCCESS(oldMUDV->
-                                  GetDefaultCharacterSet(defaultCharset),
-                                  NS_ERROR_FAILURE);
-                NS_ENSURE_SUCCESS(oldMUDV->
                                   GetForceCharacterSet(forceCharset),
                                   NS_ERROR_FAILURE);
                 NS_ENSURE_SUCCESS(oldMUDV->
                                   GetHintCharacterSet(hintCharset),
                                   NS_ERROR_FAILURE);
                 NS_ENSURE_SUCCESS(oldMUDV->
                                   GetHintCharacterSetSource(&hintCharsetSource),
                                   NS_ERROR_FAILURE);
@@ -8359,19 +8325,16 @@ nsDocShell::SetupNewViewer(nsIContentVie
                                   GetTextZoom(&textZoom),
                                   NS_ERROR_FAILURE);
                 NS_ENSURE_SUCCESS(oldMUDV->
                                   GetFullZoom(&pageZoom),
                                   NS_ERROR_FAILURE);
                 NS_ENSURE_SUCCESS(oldMUDV->
                                   GetAuthorStyleDisabled(&styleDisabled),
                                   NS_ERROR_FAILURE);
-                NS_ENSURE_SUCCESS(oldMUDV->
-                                  GetPrevDocCharacterSet(prevDocCharset),
-                                  NS_ERROR_FAILURE);
             }
         }
     }
 
     nscolor bgcolor = NS_RGBA(0, 0, 0, 0);
     // Ensure that the content viewer is destroyed *after* the GC - bug 71515
     nsCOMPtr<nsIContentViewer> kungfuDeathGrip = mContentViewer;
     if (mContentViewer) {
@@ -8416,27 +8379,23 @@ nsDocShell::SetupNewViewer(nsIContentVie
         mContentViewer = nullptr;
         NS_ERROR("ContentViewer Initialization failed");
         return NS_ERROR_FAILURE;
     }
 
     // If we have old state to copy, set the old state onto the new content
     // viewer
     if (newMUDV) {
-        NS_ENSURE_SUCCESS(newMUDV->SetDefaultCharacterSet(defaultCharset),
-                          NS_ERROR_FAILURE);
         NS_ENSURE_SUCCESS(newMUDV->SetForceCharacterSet(forceCharset),
                           NS_ERROR_FAILURE);
         NS_ENSURE_SUCCESS(newMUDV->SetHintCharacterSet(hintCharset),
                           NS_ERROR_FAILURE);
         NS_ENSURE_SUCCESS(newMUDV->
                           SetHintCharacterSetSource(hintCharsetSource),
                           NS_ERROR_FAILURE);
-        NS_ENSURE_SUCCESS(newMUDV->SetPrevDocCharacterSet(prevDocCharset),
-                          NS_ERROR_FAILURE);
         NS_ENSURE_SUCCESS(newMUDV->SetMinFontSize(minFontSize),
                           NS_ERROR_FAILURE);
         NS_ENSURE_SUCCESS(newMUDV->SetTextZoom(textZoom),
                           NS_ERROR_FAILURE);
         NS_ENSURE_SUCCESS(newMUDV->SetFullZoom(pageZoom),
                           NS_ERROR_FAILURE);
         NS_ENSURE_SUCCESS(newMUDV->SetAuthorStyleDisabled(styleDisabled),
                           NS_ERROR_FAILURE);
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -865,19 +865,20 @@ protected:
     // (This needs to be the docshell's own /or containing/ app id because the
     // containing app frame might be in another process, in which case we won't
     // find it by walking up the docshell hierarchy.)
     uint32_t mOwnOrContainingAppId;
 
 private:
     nsCString         mForcedCharset;
     nsCString         mParentCharset;
+    int32_t           mParentCharsetSource;
+    nsCOMPtr<nsIPrincipal> mParentCharsetPrincipal;
     nsTObserverArray<nsWeakPtr> mPrivacyObservers;
     nsTObserverArray<nsWeakPtr> mReflowObservers;
-    int32_t           mParentCharsetSource;
     nsCString         mOriginalUriString;
 
     // Separate function to do the actual name (i.e. not _top, _self etc.)
     // searching for FindItemWithName.
     nsresult DoFindItemWithName(const PRUnichar* aName,
                                 nsISupports* aRequestor,
                                 nsIDocShellTreeItem* aOriginalRequestor,
                                 nsIDocShellTreeItem** _retval);
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -38,17 +38,17 @@ interface nsIDOMStorage;
 interface nsIPrincipal;
 interface nsIWebBrowserPrint;
 interface nsIVariant;
 interface nsIPrivacyTransitionObserver;
 interface nsIReflowObserver;
 
 typedef unsigned long nsLoadFlags;
 
-[scriptable, builtinclass, uuid(c0bb3b19-5448-4f4d-9366-cbcd4d7cdb96)]
+[scriptable, builtinclass, uuid(4c8cd9da-4e93-42ed-9901-3781e90458d9)]
 interface nsIDocShell : nsIDocShellTreeItem
 {
   /**
    * Loads a given URI.  This will give priority to loading the requested URI
    * in the object implementing	this interface.  If it can't be loaded here
    * however, the URL dispatcher will go through its normal process of content
    * loading.
    *
@@ -592,76 +592,46 @@ interface nsIDocShell : nsIDocShellTreeI
 
   /**
    * Create a new about:blank document and content viewer.
    * @param aPrincipal the principal to use for the new document.
    */
   void createAboutBlankContentViewer(in nsIPrincipal aPrincipal);
 
   /**
-   * The charset attribute allows the user to view, hint, and set which
-   * converter is used to read the document's data.
-   *
-   * <P>Inside Mozilla all text is encoded as Unicode. By standardizing  
-   * on Unicode every piece of code that handles characters no longer 
-   * needs to: 
-   *
-   *     Have access to a character encoding parameter.
-   *     Ask is the data stateful?
-   *     Ask is the data single byte?
-   *     Ask is the data multi-byte?
-   *     If multi-byte: have access to a routine that can
-   *         determine how many bytes in the current character.
-   *
-   * When the document is read in a converter is used to convert 
-   * the document's data to Unicode.
+   * Upon getting, returns the canonical encoding label of the document
+   * currently loaded into this docshell.
    *
-   * The charset attribute provides the ability to:
-   *
-   *   See what converter was used when inputting the documents
-   *   data.
-   *
-   *   Override the character set for documents where the specified 
-   *   fallback, or auto-detected character set is incorrect
-   *
-   * Get/sets the encoding (converter) used to read the 
-   * document. Get returns the encoding used. Set forces 
-   * (overrides) the encoding. After forcing the charset the 
-   * embedding application will need to cause the data to be 
-   * reparsed in order to update the DOM / display.
-   *
-   * A force also sets the fallback encoding for this frame.
+   * Upon setting, sets forcedCharset for compatibility with legacy callers.
    */
-  attribute string charset;
+  attribute ACString charset;
 
   /**
    * Called when the user chose an encoding override from the character
    * encoding menu. Separate from the setter for the charset property to avoid
    * extensions adding noise to the data.
    */
   void gatherCharsetMenuTelemetry();
 
   /**
-   * The charset forced by the user. When the charset attribute is set this
-   * attribute is set to the same value.
-   *
-   * XXX Could this be replaced by a boolean?
+   * The charset forced by the user.
    */
   attribute ACString forcedCharset;
 
   /**
    * In a child docshell, this is the charset of the parent docshell
    */
-  attribute ACString parentCharset;
-
-  /*
-   * In a child docshell, this is the source of parentCharset
-   * @see nsCharsetSource.h
-   */
-  attribute int32_t parentCharsetSource;
+  [noscript, notxpcom, nostdcall] void setParentCharset(
+    in ACString parentCharset,
+    in int32_t parentCharsetSource,
+    in nsIPrincipal parentCharsetPrincipal);
+  [noscript, notxpcom, nostdcall] void getParentCharset(
+    out ACString parentCharset,
+    out int32_t parentCharsetSource,
+    out nsIPrincipal parentCharsetPrincipal);
 
   /**
    * Add an observer to the list of parties to be notified when this docshell's
    * private browsing status is changed. |obs| must support weak references.
    */
   void addWeakPrivacyTransitionObserver(in nsIPrivacyTransitionObserver obs);
 
   /**
--- a/docshell/base/nsIMarkupDocumentViewer.idl
+++ b/docshell/base/nsIMarkupDocumentViewer.idl
@@ -18,17 +18,17 @@ interface nsIDOMNode;
 template<class T> class nsCOMPtr;
 template<class T> class nsTArray;
 %}
 
 interface nsIMarkupDocumentViewer;
 
 [ref] native nsIMarkupDocumentViewerTArray(nsTArray<nsCOMPtr<nsIMarkupDocumentViewer> >);
 
-[scriptable, uuid(23326580-e6ce-4ee1-94b8-f1d9424a9977)]
+[scriptable, uuid(6acfadef-22ee-4924-be6c-776e8def6e1b)]
 interface nsIMarkupDocumentViewer : nsISupports
 {
 
 	/*
 	Scrolls to a given DOM content node. 
 	*/
 	void scrollToNode(in nsIDOMNode node);
 
@@ -36,42 +36,32 @@ interface nsIMarkupDocumentViewer : nsIS
 	attribute float textZoom;
 
 	/** The amount by which to scale all lengths. Default is 1.0. */
 	attribute float fullZoom;
 
 	/** Disable entire author style level (including HTML presentation hints) */
 	attribute boolean authorStyleDisabled;
 
-	/*
-	XXX Comment here!
-	*/
-	attribute ACString defaultCharacterSet;
-
 	/**
 	 * XXX comm-central only: bug 829543. Not the Character Encoding menu in 
      * browser!
 	 */
 	attribute ACString forceCharacterSet;
 
 	/**
 	 * XXX comm-central only: bug 829543.
 	 */
 	attribute ACString hintCharacterSet;
 
 	/**
 	 * XXX comm-central only: bug 829543.
 	 */
 	attribute int32_t hintCharacterSetSource;
 
-	/*
-	character set from prev document 
-	*/
-	attribute ACString prevDocCharacterSet;
-
 	//void GetCharacterSetHint(in wstring hintCharset, in int32_t charsetSource);
 
   /**
    * Requests the size of the content to the container.
    */
   void getContentSize(out long width, out long height);
 
   /**
--- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
@@ -766,62 +766,16 @@ nsWindowWatcher::OpenWindowInternal(nsID
   if (windowNeedsName) {
     if (nameSpecified && !name.LowerCaseEqualsLiteral("_blank")) {
       newDocShellItem->SetName(name);
     } else {
       newDocShellItem->SetName(EmptyString());
     }
   }
 
-  // Inherit the right character set into the new window to use as a fallback
-  // in the event the document being loaded does not specify a charset.  When
-  // aCalledFromJS is true, we want to use the character set of the document in
-  // the caller; otherwise we want to use the character set of aParent's
-  // docshell. Failing to set this charset is not fatal, so we want to continue
-  // in the face of errors.
-  nsCOMPtr<nsIContentViewer> newCV;
-  newDocShell->GetContentViewer(getter_AddRefs(newCV));
-  nsCOMPtr<nsIMarkupDocumentViewer> newMuCV = do_QueryInterface(newCV);
-  if (newMuCV) {
-    nsCOMPtr<nsIDocShellTreeItem> parentItem;
-    GetWindowTreeItem(aParent, getter_AddRefs(parentItem));
-
-    if (aCalledFromJS) {
-      nsCOMPtr<nsIDocShellTreeItem> callerItem = GetCallerTreeItem(parentItem);
-      nsCOMPtr<nsPIDOMWindow> callerWin = do_GetInterface(callerItem);
-      if (callerWin) {
-        nsCOMPtr<nsIDocument> doc = callerWin->GetExtantDoc();
-        if (doc) {
-          newMuCV->SetDefaultCharacterSet(doc->GetDocumentCharacterSet());
-        }
-      }
-    }
-    else {
-      nsCOMPtr<nsIDocShell> parentDocshell = do_QueryInterface(parentItem);
-      // parentDocshell may be null if the parent got closed in the meantime
-      if (parentDocshell) {
-        nsCOMPtr<nsIContentViewer> parentCV;
-        parentDocshell->GetContentViewer(getter_AddRefs(parentCV));
-        nsCOMPtr<nsIMarkupDocumentViewer> parentMuCV =
-          do_QueryInterface(parentCV);
-        if (parentMuCV) {
-          nsAutoCString charset;
-          nsresult res = parentMuCV->GetDefaultCharacterSet(charset);
-          if (NS_SUCCEEDED(res)) {
-            newMuCV->SetDefaultCharacterSet(charset);
-          }
-          res = parentMuCV->GetPrevDocCharacterSet(charset);
-          if (NS_SUCCEEDED(res)) {
-            newMuCV->SetPrevDocCharacterSet(charset);
-          }
-        }
-      }
-    }
-  }
-
   // Now we have to set the right opener principal on the new window.  Note
   // that we have to do this _before_ starting any URI loads, thanks to the
   // sync nature of javascript: loads.  Since this is the only place where we
   // set said opener principal, we need to do it for all URIs, including
   // chrome ones.  So to deal with the mess that is bug 79775, just press on in
   // a reasonable way even if GetSubjectPrincipal fails.  In that case, just
   // use a null subjectPrincipal.
   nsCOMPtr<nsIPrincipal> subjectPrincipal;
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -411,19 +411,17 @@ protected:
 #ifdef DEBUG
   FILE* mDebugFile;
 #endif // DEBUG
 #endif // NS_PRINTING
 
   /* character set member data */
   int32_t mHintCharsetSource;
   nsCString mHintCharset;
-  nsCString mDefaultCharacterSet;
   nsCString mForceCharacterSet;
-  nsCString mPrevDocCharacterSet;
   
   bool mIsPageMode;
   bool mCallerIsClosingWindow;
   bool mInitializedForPrintPreview;
   bool mHidden;
 };
 
 class nsPrintEventDispatcher
@@ -2998,57 +2996,16 @@ nsDocumentViewer::StopEmulatingMedium()
   if (mDocument) {
     mDocument->EnumerateExternalResources(ExtResourceStopEmulatingMedium,
                                           nullptr);
   }
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDocumentViewer::GetDefaultCharacterSet(nsACString& aDefaultCharacterSet)
-{
-  if (mDefaultCharacterSet.IsEmpty())
-  {
-    const nsAdoptingCString& defCharset =
-      Preferences::GetLocalizedCString("intl.charset.default");
-
-    // Don't let the user break things by setting intl.charset.default to
-    // not a rough ASCII superset
-    nsAutoCString canonical;
-    if (EncodingUtils::FindEncodingForLabel(defCharset, canonical) &&
-        EncodingUtils::IsAsciiCompatible(canonical)) {
-      mDefaultCharacterSet = canonical;
-    } else {
-      mDefaultCharacterSet.AssignLiteral("windows-1252");
-    }
-  }
-  aDefaultCharacterSet = mDefaultCharacterSet;
-  return NS_OK;
-}
-
-static void
-SetChildDefaultCharacterSet(nsIMarkupDocumentViewer* aChild, void* aClosure)
-{
-  const nsACString* charset = static_cast<nsACString*>(aClosure);
-  aChild->SetDefaultCharacterSet(*charset);
-}
-
-NS_IMETHODIMP
-nsDocumentViewer::SetDefaultCharacterSet(const nsACString& aDefaultCharacterSet)
-{
-  mDefaultCharacterSet = aDefaultCharacterSet;  // this does a copy of aDefaultCharacterSet
-  // now set the default char set on all children of mContainer
-  CallChildren(SetChildDefaultCharacterSet, (void*) &aDefaultCharacterSet);
-  return NS_OK;
-}
-
-// XXX: SEMANTIC CHANGE!
-//      returns a copy of the string.  Caller is responsible for freeing result
-//      using Recycle(aForceCharacterSet)
 NS_IMETHODIMP nsDocumentViewer::GetForceCharacterSet(nsACString& aForceCharacterSet)
 {
   aForceCharacterSet = mForceCharacterSet;
   return NS_OK;
 }
 
 static void
 SetChildForceCharacterSet(nsIMarkupDocumentViewer* aChild, void* aClosure)
@@ -3061,19 +3018,16 @@ NS_IMETHODIMP
 nsDocumentViewer::SetForceCharacterSet(const nsACString& aForceCharacterSet)
 {
   mForceCharacterSet = aForceCharacterSet;
   // now set the force char set on all children of mContainer
   CallChildren(SetChildForceCharacterSet, (void*) &aForceCharacterSet);
   return NS_OK;
 }
 
-// XXX: SEMANTIC CHANGE!
-//      returns a copy of the string.  Caller is responsible for freeing result
-//      using Recycle(aHintCharacterSet)
 NS_IMETHODIMP nsDocumentViewer::GetHintCharacterSet(nsACString& aHintCharacterSet)
 {
 
   if(kCharsetUninitialized == mHintCharsetSource) {
     aHintCharacterSet.Truncate();
   } else {
     aHintCharacterSet = mHintCharset;
     // this can't possibly be right.  we can't set a value just because somebody got a related value!
@@ -3085,41 +3039,16 @@ NS_IMETHODIMP nsDocumentViewer::GetHintC
 NS_IMETHODIMP nsDocumentViewer::GetHintCharacterSetSource(int32_t *aHintCharacterSetSource)
 {
   NS_ENSURE_ARG_POINTER(aHintCharacterSetSource);
 
   *aHintCharacterSetSource = mHintCharsetSource;
   return NS_OK;
 }
 
-
-NS_IMETHODIMP nsDocumentViewer::GetPrevDocCharacterSet(nsACString& aPrevDocCharacterSet)
-{
-  aPrevDocCharacterSet = mPrevDocCharacterSet;
-
-  return NS_OK;
-}
-
-static void
-SetChildPrevDocCharacterSet(nsIMarkupDocumentViewer* aChild, void* aClosure)
-{
-  const nsACString* charset = static_cast<nsACString*>(aClosure);
-  aChild->SetPrevDocCharacterSet(*charset);
-}
-
-
-NS_IMETHODIMP
-nsDocumentViewer::SetPrevDocCharacterSet(const nsACString& aPrevDocCharacterSet)
-{
-  mPrevDocCharacterSet = aPrevDocCharacterSet;  
-  CallChildren(SetChildPrevDocCharacterSet, (void*) &aPrevDocCharacterSet);
-  return NS_OK;
-}
-
-
 static void
 SetChildHintCharacterSetSource(nsIMarkupDocumentViewer* aChild, void* aClosure)
 {
   aChild->SetHintCharacterSetSource(NS_PTR_TO_INT32(aClosure));
 }
 
 NS_IMETHODIMP
 nsDocumentViewer::SetHintCharacterSetSource(int32_t aHintCharacterSetSource)
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -216,49 +216,16 @@ nsHtml5TreeOpExecutor::FlushPendingNotif
 
 void
 nsHtml5TreeOpExecutor::SetDocumentCharsetAndSource(nsACString& aCharset, int32_t aCharsetSource)
 {
   if (mDocument) {
     mDocument->SetDocumentCharacterSetSource(aCharsetSource);
     mDocument->SetDocumentCharacterSet(aCharset);
   }
-  if (mDocShell) {
-    // the following logic to get muCV is copied from
-    // nsHTMLDocument::StartDocumentLoad
-    // We need to call muCV->SetPrevDocCharacterSet here in case
-    // the charset is detected by parser DetectMetaTag
-    nsCOMPtr<nsIMarkupDocumentViewer> mucv;
-    nsCOMPtr<nsIContentViewer> cv;
-    mDocShell->GetContentViewer(getter_AddRefs(cv));
-    if (cv) {
-      mucv = do_QueryInterface(cv);
-    } else {
-      // in this block of code, if we get an error result, we return
-      // it but if we get a null pointer, that's perfectly legal for
-      // parent and parentContentViewer
-      if (!mDocShell) {
-    	  return;
-      }
-      nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
-      mDocShell->GetSameTypeParent(getter_AddRefs(parentAsItem));
-      nsCOMPtr<nsIDocShell> parent(do_QueryInterface(parentAsItem));
-      if (parent) {
-        nsCOMPtr<nsIContentViewer> parentContentViewer;
-        nsresult rv =
-          parent->GetContentViewer(getter_AddRefs(parentContentViewer));
-        if (NS_SUCCEEDED(rv) && parentContentViewer) {
-          mucv = do_QueryInterface(parentContentViewer);
-        }
-      }
-    }
-    if (mucv) {
-      mucv->SetPrevDocCharacterSet(aCharset);
-    }
-  }
 }
 
 nsISupports*
 nsHtml5TreeOpExecutor::GetTarget()
 {
   return mDocument;
 }
 
--- a/parser/nsCharsetSource.h
+++ b/parser/nsCharsetSource.h
@@ -3,24 +3,23 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsCharsetSource_h_
 #define nsCharsetSource_h_
 
 // note: the value order defines the priority; higher numbers take priority
 #define kCharsetUninitialized           0
 #define kCharsetFromWeakDocTypeDefault  1
-#define kCharsetFromUserDefault         2
-#define kCharsetFromDocTypeDefault      3 // This and up confident for XHR
-#define kCharsetFromCache               4
-#define kCharsetFromParentFrame         5
-#define kCharsetFromAutoDetection       6
-#define kCharsetFromHintPrevDoc         7
-#define kCharsetFromMetaPrescan         8 // this one and smaller: HTML5 Tentative
-#define kCharsetFromMetaTag             9 // this one and greater: HTML5 Confident
-#define kCharsetFromIrreversibleAutoDetection 10
-#define kCharsetFromChannel            11
-#define kCharsetFromOtherComponent     12
-#define kCharsetFromParentForced       13 // propagates to child frames
-#define kCharsetFromUserForced         14 // propagates to child frames
-#define kCharsetFromByteOrderMark      15
+#define kCharsetFromDocTypeDefault      2 // This and up confident for XHR
+#define kCharsetFromCache               3
+#define kCharsetFromParentFrame         4
+#define kCharsetFromAutoDetection       5
+#define kCharsetFromHintPrevDoc         6
+#define kCharsetFromMetaPrescan         7 // this one and smaller: HTML5 Tentative
+#define kCharsetFromMetaTag             8 // this one and greater: HTML5 Confident
+#define kCharsetFromIrreversibleAutoDetection 9
+#define kCharsetFromChannel            10
+#define kCharsetFromOtherComponent     11
+#define kCharsetFromParentForced       12 // propagates to child frames
+#define kCharsetFromUserForced         13 // propagates to child frames
+#define kCharsetFromByteOrderMark      14
 
 #endif /* nsCharsetSource_h_ */
--- a/toolkit/components/viewsource/content/viewSource.js
+++ b/toolkit/components/viewsource/content/viewSource.js
@@ -105,19 +105,19 @@ function viewSource(url)
     var charset;
     if (window.arguments.length >= 2) {
       arg = window.arguments[1];
 
       try {
         if (typeof(arg) == "string" && arg.indexOf('charset=') != -1) {
           var arrayArgComponents = arg.split('=');
           if (arrayArgComponents) {
-            //we should "inherit" the charset menu setting in a new window
+            // Remember the charset here so that it can be used below in case
+            // the document had a forced charset.
             charset = arrayArgComponents[1];
-            gBrowser.markupDocumentViewer.defaultCharacterSet = charset;
           }
         }
       } catch (ex) {
         // Ignore the failure and keep processing arguments...
       }
     }
     // If the document had a forced charset, set it here also
     if (window.arguments.length >= 5) {