Browse Source

Various console backports

Ian Neal 8 months ago
parent
commit
8a66233dbe
30 changed files with 5925 additions and 68 deletions
  1. 84 0
      comm-release/patches/1445374-61a1.patch
  2. 1 0
      comm-release/patches/series
  3. 551 0
      mozilla-release/patches/1037335-1-59a1.patch
  4. 41 0
      mozilla-release/patches/1037335-2-59a1.patch
  5. 57 0
      mozilla-release/patches/1037335-3no4or5-59a1.patch
  6. 158 0
      mozilla-release/patches/1037335-6-59a1.patch
  7. 42 0
      mozilla-release/patches/1403866-58a1.patch
  8. 393 0
      mozilla-release/patches/1418243-1no2-59a1.patch
  9. 194 0
      mozilla-release/patches/1418243-3-59a1.patch
  10. 676 0
      mozilla-release/patches/1425574-1-59a1.patch
  11. 156 0
      mozilla-release/patches/1425574-2-59a1.patch
  12. 157 0
      mozilla-release/patches/1425574-3-59a1.patch
  13. 500 0
      mozilla-release/patches/1425574-4-59a1.patch
  14. 157 0
      mozilla-release/patches/1425574-5-59a1.patch
  15. 25 0
      mozilla-release/patches/1425574-6-59a1.patch
  16. 148 0
      mozilla-release/patches/1425574-7-59a1.patch
  17. 459 0
      mozilla-release/patches/1425574-8-59a1.patch
  18. 190 0
      mozilla-release/patches/1425574-9-59a1.patch
  19. 51 0
      mozilla-release/patches/1425993-59a1.patch
  20. 37 42
      mozilla-release/patches/1434686-4-60a1.patch
  21. 30 0
      mozilla-release/patches/1440816-1-60a1.patch
  22. 250 0
      mozilla-release/patches/1440816-2-60a1.patch
  23. 1326 0
      mozilla-release/patches/1443079-61a1.patch
  24. 3 3
      mozilla-release/patches/1443081-16-client-webconsole-61a1.patch
  25. 11 11
      mozilla-release/patches/1445302-61a1.patch
  26. 73 0
      mozilla-release/patches/1447210-1-61a1.patch
  27. 75 0
      mozilla-release/patches/1447210-2-61a1.patch
  28. 45 0
      mozilla-release/patches/1447422-61a1.patch
  29. 12 12
      mozilla-release/patches/1762733-removepluginprefs-25312.patch
  30. 23 0
      mozilla-release/patches/series

+ 84 - 0
comm-release/patches/1445374-61a1.patch

@@ -0,0 +1,84 @@
+# HG changeset patch
+# User Jorg K <jorgk@jorgk.com>
+# Date 1520965094 -3600
+# Node ID 9bd75170c7aea42af5de3c7de1da9ff9a0b84354
+# Parent  733708a0681b8222037d1e3d4f9a3d780c2739c4
+Bug 1445374 - Port Bug 1443079: nsIScriptError::Init() has another argument now. rs=bustage-fix DONTBUILD
+
+diff --git a/calendar/base/backend/libical/calUtils.cpp b/calendar/base/backend/libical/calUtils.cpp
+--- a/calendar/base/backend/libical/calUtils.cpp
++++ b/calendar/base/backend/libical/calUtils.cpp
+@@ -11,25 +11,25 @@ extern "C" {
+ }
+ 
+ namespace cal {
+ 
+ nsresult logError(const nsAString& msg) {
+     nsresult rc;
+     nsCOMPtr<nsIScriptError> const scriptError(do_CreateInstance("@mozilla.org/scripterror;1", &rc));
+     NS_ENSURE_SUCCESS(rc, rc);
+-    rc = scriptError->Init(msg, EmptyString(), EmptyString(), 0, 0, nsIScriptError::errorFlag, "calendar");
++    rc = scriptError->Init(msg, EmptyString(), EmptyString(), 0, 0, nsIScriptError::errorFlag, "calendar", false);
+     return getConsoleService()->LogMessage(scriptError);
+ }
+ 
+ nsresult logWarning(const nsAString& msg) {
+     nsresult rc;
+     nsCOMPtr<nsIScriptError> const scriptError(do_CreateInstance("@mozilla.org/scripterror;1", &rc));
+     NS_ENSURE_SUCCESS(rc, rc);
+-    rc = scriptError->Init(msg, EmptyString(), EmptyString(), 0, 0, nsIScriptError::warningFlag, "calendar");
++    rc = scriptError->Init(msg, EmptyString(), EmptyString(), 0, 0, nsIScriptError::warningFlag, "calendar", false);
+     return getConsoleService()->LogMessage(scriptError);
+ }
+ 
+ nsresult log(char16_t const* msg) {
+     return getConsoleService()->LogStringMessage(msg);
+ }
+ 
+ nsCOMPtr<calITimezone> detectTimezone(icaltimetype const& icalt,
+diff --git a/mailnews/base/util/nsMsgDBFolder.cpp b/mailnews/base/util/nsMsgDBFolder.cpp
+--- a/mailnews/base/util/nsMsgDBFolder.cpp
++++ b/mailnews/base/util/nsMsgDBFolder.cpp
+@@ -3594,17 +3594,18 @@ NS_IMETHODIMP nsMsgDBFolder::GetPretties
+ 
+     if (cs) {
+       nsCString msg(__FUNCTION__);
+       msg.AppendLiteral(" is deprecated and will be removed soon.");
+ 
+       nsCOMPtr<nsIScriptError> e = do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
+       if (e && NS_SUCCEEDED(e->Init(NS_ConvertUTF8toUTF16(msg), EmptyString(),
+                                     EmptyString(), 0, 0,
+-                                    nsIScriptError::warningFlag, "mailnews"))) {
++                                    nsIScriptError::warningFlag, "mailnews",
++                                    false))) {
+         cs->LogMessage(e);
+       }
+     }
+   }
+   NS_WARNING("You are trying to use the deprecated attribute 'prettiestName'.");
+ 
+   if (NS_SUCCEEDED(GetPrettyName(name)))
+     return NS_OK;
+diff --git a/mailnews/base/util/nsMsgUtils.cpp b/mailnews/base/util/nsMsgUtils.cpp
+--- a/mailnews/base/util/nsMsgUtils.cpp
++++ b/mailnews/base/util/nsMsgUtils.cpp
+@@ -100,17 +100,18 @@ NS_MSG_BASE void MsgLogToConsole4(const 
+   if (NS_WARN_IF(!console))
+     return;
+   if (NS_FAILED(scriptError->Init(aErrorText,
+                                   aFilename,
+                                   EmptyString(),
+                                   aLinenumber,
+                                   0,
+                                   aFlag,
+-                                  "mailnews")))
++                                  "mailnews",
++                                  false)))
+     return;
+   console->LogMessage(scriptError);
+   return;
+ }
+ 
+ using namespace mozilla;
+ using namespace mozilla::net;
+ 

+ 1 - 0
comm-release/patches/series

@@ -2147,3 +2147,4 @@ TOP-1872623-cancelbookmark-25319.patch
 1466297-62a1.patch
 1877001-port1407891-25319.patch
 1879726-port1398229-25319.patch
+1445374-61a1.patch

+ 551 - 0
mozilla-release/patches/1037335-1-59a1.patch

@@ -0,0 +1,551 @@
+# HG changeset patch
+# User Chung-Sheng Fu <cfu@mozilla.com>
+# Date 1511967180 -7200
+# Node ID 48ba62a0feb0c7431807e0d586c0e310da21f721
+# Parent  8d6c019576925b5adba7880c62dde3cb006ea9f4
+Bug 1037335 - Implement security policy violation event. r=ckerschb,smaug
+
+MozReview-Commit-ID: 4BYThUXduI4
+
+diff --git a/dom/interfaces/security/nsIContentSecurityPolicy.idl b/dom/interfaces/security/nsIContentSecurityPolicy.idl
+--- a/dom/interfaces/security/nsIContentSecurityPolicy.idl
++++ b/dom/interfaces/security/nsIContentSecurityPolicy.idl
+@@ -1,23 +1,20 @@
+ /* 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 "nsISerializable.idl"
+ #include "nsIContentPolicy.idl"
+ 
+ interface nsIURI;
+-interface nsIChannel;
+ interface nsIDocShell;
+ interface nsIDOMDocument;
+ interface nsIEventTarget;
+ interface nsIPrincipal;
+-interface nsIScriptElement;
+-interface nsIURI;
+ 
+ /**
+  * nsIContentSecurityPolicy
+  * Describes an XPCOM component used to model and enforce CSPs.  Instances of
+  * this class may have multiple policies within them, but there should only be
+  * one of these per document/principal.
+  */
+ 
+diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp
+--- a/dom/security/nsCSPContext.cpp
++++ b/dom/security/nsCSPContext.cpp
+@@ -838,47 +838,39 @@ StripURIForReporting(nsIURI* aURI,
+     aURI->GetPrePath(outStrippedURI);
+     return;
+   }
+ 
+   // 3) Return uri, with any fragment component removed.
+   aURI->GetSpecIgnoringRef(outStrippedURI);
+ }
+ 
+-/**
+- * Sends CSP violation reports to all sources listed under report-uri.
+- *
+- * @param aBlockedContentSource
+- *        Either a CSP Source (like 'self', as string) or nsIURI: the source
+- *        of the violation.
+- * @param aOriginalUri
+- *        The original URI if the blocked content is a redirect, else null
+- * @param aViolatedDirective
+- *        the directive that was violated (string).
+- * @param aSourceFile
+- *        name of the file containing the inline script violation
+- * @param aScriptSample
+- *        a sample of the violating inline script
+- * @param aLineNum
+- *        source line number of the violation (if available)
+- */
+ nsresult
+-nsCSPContext::SendReports(nsISupports* aBlockedContentSource,
+-                          nsIURI* aOriginalURI,
+-                          nsAString& aViolatedDirective,
+-                          uint32_t aViolatedPolicyIndex,
+-                          nsAString& aSourceFile,
+-                          nsAString& aScriptSample,
+-                          uint32_t aLineNum)
++nsCSPContext::GatherSecurityPolicyViolationEventData(
++  nsISupports* aBlockedContentSource,
++  nsIURI* aOriginalURI,
++  nsAString& aViolatedDirective,
++  uint32_t aViolatedPolicyIndex,
++  nsAString& aSourceFile,
++  nsAString& aScriptSample,
++  uint32_t aLineNum,
++  mozilla::dom::SecurityPolicyViolationEventInit& aViolationEventInit)
+ {
+   NS_ENSURE_ARG_MAX(aViolatedPolicyIndex, mPolicies.Length() - 1);
+ 
+-  dom::CSPReport report;
+   nsresult rv;
+ 
++  // document-uri
++  nsAutoCString reportDocumentURI;
++  StripURIForReporting(mSelfURI, mSelfURI, reportDocumentURI);
++  aViolationEventInit.mDocumentURI = NS_ConvertUTF8toUTF16(reportDocumentURI);
++
++  // referrer
++  aViolationEventInit.mReferrer = mReferrer;
++
+   // blocked-uri
+   if (aBlockedContentSource) {
+     nsAutoCString reportBlockedURI;
+     nsCOMPtr<nsIURI> uri = do_QueryInterface(aBlockedContentSource);
+     // could be a string or URI
+     if (uri) {
+       StripURIForReporting(uri, mSelfURI, reportBlockedURI);
+     } else {
+@@ -887,89 +879,150 @@ nsCSPContext::SendReports(nsISupports* a
+         cstr->GetData(reportBlockedURI);
+       }
+     }
+     if (reportBlockedURI.IsEmpty()) {
+       // this can happen for frame-ancestors violation where the violating
+       // ancestor is cross-origin.
+       NS_WARNING("No blocked URI (null aBlockedContentSource) for CSP violation report.");
+     }
+-    report.mCsp_report.mBlocked_uri = NS_ConvertUTF8toUTF16(reportBlockedURI);
++    aViolationEventInit.mBlockedURI = NS_ConvertUTF8toUTF16(reportBlockedURI);
+   }
+ 
+-  // document-uri
+-  nsAutoCString reportDocumentURI;
+-  StripURIForReporting(mSelfURI, mSelfURI, reportDocumentURI);
+-  report.mCsp_report.mDocument_uri = NS_ConvertUTF8toUTF16(reportDocumentURI);
++  // violated-directive
++  aViolationEventInit.mViolatedDirective = aViolatedDirective;
++
++  // effective-directive
++  aViolationEventInit.mEffectiveDirective = aViolatedDirective;
+ 
+   // original-policy
+   nsAutoString originalPolicy;
+   rv = this->GetPolicyString(aViolatedPolicyIndex, originalPolicy);
+   NS_ENSURE_SUCCESS(rv, rv);
+-  report.mCsp_report.mOriginal_policy = originalPolicy;
+-
+-  // referrer
+-  if (!mReferrer.IsEmpty()) {
+-    report.mCsp_report.mReferrer = mReferrer;
+-  }
+-
+-  // violated-directive
+-  report.mCsp_report.mViolated_directive = aViolatedDirective;
++  aViolationEventInit.mOriginalPolicy = originalPolicy;
+ 
+   // source-file
+   if (!aSourceFile.IsEmpty()) {
+     // if aSourceFile is a URI, we have to make sure to strip fragments
+     nsCOMPtr<nsIURI> sourceURI;
+     NS_NewURI(getter_AddRefs(sourceURI), aSourceFile);
+     if (sourceURI) {
+       nsAutoCString spec;
+       sourceURI->GetSpecIgnoringRef(spec);
+       aSourceFile = NS_ConvertUTF8toUTF16(spec);
+     }
++    aViolationEventInit.mSourceFile = aSourceFile;
++  }
++
++  // sample
++  aViolationEventInit.mSample = aScriptSample;
++
++  // disposition
++  aViolationEventInit.mDisposition = mPolicies[aViolatedPolicyIndex]->getReportOnlyFlag()
++    ? mozilla::dom::SecurityPolicyViolationEventDisposition::Report
++    : mozilla::dom::SecurityPolicyViolationEventDisposition::Enforce;
++
++  // status-code
++  uint16_t statusCode = 0;
++  {
++    nsCOMPtr<nsIDocument> doc = do_QueryReferent(mLoadingContext);
++    if (doc) {
++      nsCOMPtr<nsIHttpChannel> channel = do_QueryInterface(doc->GetChannel());
++      if (channel) {
++        uint32_t responseStatus = 0;
++        nsresult rv = channel->GetResponseStatus(&responseStatus);
++        if (NS_SUCCEEDED(rv) && (responseStatus <= UINT16_MAX)) {
++          statusCode = static_cast<uint16_t>(responseStatus);
++        }
++      }
++    }
++  }
++  aViolationEventInit.mStatusCode = statusCode;
++
++  // line-number
++  aViolationEventInit.mLineNumber = aLineNum;
++
++  // column-number
++  // TODO: Set correct column number.
++  aViolationEventInit.mColumnNumber = 0;
++
++  aViolationEventInit.mBubbles = true;
++  aViolationEventInit.mComposed = true;
++
++  return NS_OK;
++}
++
++nsresult
++nsCSPContext::SendReports(
++  const mozilla::dom::SecurityPolicyViolationEventInit& aViolationEventInit,
++  uint32_t aViolatedPolicyIndex)
++{
++  NS_ENSURE_ARG_MAX(aViolatedPolicyIndex, mPolicies.Length() - 1);
++
++  dom::CSPReport report;
++
++  // blocked-uri
++  report.mCsp_report.mBlocked_uri = aViolationEventInit.mBlockedURI;
++
++  // document-uri
++  report.mCsp_report.mDocument_uri = aViolationEventInit.mDocumentURI;
++
++  // original-policy
++  report.mCsp_report.mOriginal_policy = aViolationEventInit.mOriginalPolicy;
++
++  // referrer
++  report.mCsp_report.mReferrer = aViolationEventInit.mReferrer;
++
++  // violated-directive
++  report.mCsp_report.mViolated_directive = aViolationEventInit.mViolatedDirective;
++
++  // source-file
++  if (!aViolationEventInit.mSourceFile.IsEmpty()) {
+     report.mCsp_report.mSource_file.Construct();
+-    report.mCsp_report.mSource_file.Value() = aSourceFile;
++    report.mCsp_report.mSource_file.Value() = aViolationEventInit.mSourceFile;
+   }
+ 
+   // script-sample
+-  if (!aScriptSample.IsEmpty()) {
++  if (!aViolationEventInit.mSample.IsEmpty()) {
+     report.mCsp_report.mScript_sample.Construct();
+-    report.mCsp_report.mScript_sample.Value() = aScriptSample;
++    report.mCsp_report.mScript_sample.Value() = aViolationEventInit.mSample;
+   }
+ 
+   // line-number
+-  if (aLineNum != 0) {
++  if (aViolationEventInit.mLineNumber != 0) {
+     report.mCsp_report.mLine_number.Construct();
+-    report.mCsp_report.mLine_number.Value() = aLineNum;
++    report.mCsp_report.mLine_number.Value() = aViolationEventInit.mLineNumber;
+   }
+ 
+   nsString csp_report;
+   if (!report.ToJSON(csp_report)) {
+     return NS_ERROR_FAILURE;
+   }
+ 
+   // ---------- Assembled, now send it to all the report URIs ----------- //
+ 
+   nsTArray<nsString> reportURIs;
+   mPolicies[aViolatedPolicyIndex]->getReportURIs(reportURIs);
+ 
+-
+   nsCOMPtr<nsIDocument> doc = do_QueryReferent(mLoadingContext);
+   nsCOMPtr<nsIURI> reportURI;
+   nsCOMPtr<nsIChannel> reportChannel;
+ 
++  nsresult rv;
+   for (uint32_t r = 0; r < reportURIs.Length(); r++) {
+     nsAutoCString reportURICstring = NS_ConvertUTF16toUTF8(reportURIs[r]);
+     // try to create a new uri from every report-uri string
+     rv = NS_NewURI(getter_AddRefs(reportURI), reportURIs[r]);
+     if (NS_FAILED(rv)) {
+       const char16_t* params[] = { reportURIs[r].get() };
+       CSPCONTEXTLOG(("Could not create nsIURI for report URI %s",
+                      reportURICstring.get()));
+       logToConsole("triedToSendReport", params, ArrayLength(params),
+-                   aSourceFile, aScriptSample, aLineNum, 0, nsIScriptError::errorFlag);
++                   aViolationEventInit.mSourceFile, aViolationEventInit.mSample,
++                   aViolationEventInit.mLineNumber, 0, nsIScriptError::errorFlag);
+       continue; // don't return yet, there may be more URIs
+     }
+ 
+     // try to create a new channel for every report-uri
+     nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL | nsIChannel::LOAD_CLASSIFY_URI;
+     if (doc) {
+       rv = NS_NewChannel(getter_AddRefs(reportChannel),
+                          reportURI,
+@@ -1000,17 +1053,18 @@ nsCSPContext::SendReports(nsISupports* a
+     // log a warning to console if scheme is not http or https
+     bool isHttpScheme =
+       (NS_SUCCEEDED(reportURI->SchemeIs("http", &isHttpScheme)) && isHttpScheme) ||
+       (NS_SUCCEEDED(reportURI->SchemeIs("https", &isHttpScheme)) && isHttpScheme);
+ 
+     if (!isHttpScheme) {
+       const char16_t* params[] = { reportURIs[r].get() };
+       logToConsole("reportURInotHttpsOrHttp2", params, ArrayLength(params),
+-                   aSourceFile, aScriptSample, aLineNum, 0, nsIScriptError::errorFlag);
++                   aViolationEventInit.mSourceFile, aViolationEventInit.mSample,
++                   aViolationEventInit.mLineNumber, 0, nsIScriptError::errorFlag);
+       continue;
+     }
+ 
+     // make sure this is an anonymous request (no cookies) so in case the
+     // policy URI is injected, it can't be abused for CSRF.
+     nsLoadFlags flags;
+     rv = reportChannel->GetLoadFlags(&flags);
+     NS_ENSURE_SUCCESS(rv, rv);
+@@ -1065,24 +1119,45 @@ nsCSPContext::SendReports(nsISupports* a
+     // SetRequestContext is not given a channel).  This should fail quietly and
+     // not return an error since it's really ok if reports don't go out, but
+     // it's good to log the error locally.
+ 
+     if (NS_FAILED(rv)) {
+       const char16_t* params[] = { reportURIs[r].get() };
+       CSPCONTEXTLOG(("AsyncOpen failed for report URI %s", NS_ConvertUTF16toUTF8(params[0]).get()));
+       logToConsole("triedToSendReport", params, ArrayLength(params),
+-                   aSourceFile, aScriptSample, aLineNum, 0, nsIScriptError::errorFlag);
++                   aViolationEventInit.mSourceFile, aViolationEventInit.mSample,
++                   aViolationEventInit.mLineNumber, 0, nsIScriptError::errorFlag);
+     } else {
+       CSPCONTEXTLOG(("Sent violation report to URI %s", reportURICstring.get()));
+     }
+   }
+   return NS_OK;
+ }
+ 
++nsresult
++nsCSPContext::FireViolationEvent(
++  const mozilla::dom::SecurityPolicyViolationEventInit& aViolationEventInit)
++{
++  nsCOMPtr<nsIDocument> doc = do_QueryReferent(mLoadingContext);
++  if (!doc) {
++    return NS_OK;
++  }
++
++  RefPtr<mozilla::dom::Event> event =
++    mozilla::dom::SecurityPolicyViolationEvent::Constructor(
++      doc,
++      NS_LITERAL_STRING("securitypolicyviolation"),
++      aViolationEventInit);
++  event->SetTrusted(true);
++
++  bool rv;
++  return doc->DispatchEvent(event, &rv);
++}
++
+ /**
+  * Dispatched from the main thread to send reports for one CSP violation.
+  */
+ class CSPReportSenderRunnable final : public Runnable
+ {
+   public:
+     CSPReportSenderRunnable(nsISupports* aBlockedContentSource,
+                             nsIURI* aOriginalURI,
+@@ -1119,28 +1194,34 @@ class CSPReportSenderRunnable final : pu
+         mObserverSubject = do_QueryInterface(supportscstr);
+       }
+     }
+ 
+     NS_IMETHOD Run() override
+     {
+       MOZ_ASSERT(NS_IsMainThread());
+ 
++      // 0) prepare violation data
++      mozilla::dom::SecurityPolicyViolationEventInit init;
++      mCSPContext->GatherSecurityPolicyViolationEventData(
++        mBlockedContentSource, mOriginalURI,
++        mViolatedDirective, mViolatedPolicyIndex,
++        mSourceFile, mScriptSample, mLineNum,
++        init);
++
+       // 1) notify observers
+       nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
+       NS_ASSERTION(observerService, "needs observer service");
+       nsresult rv = observerService->NotifyObservers(mObserverSubject,
+                                                      CSP_VIOLATION_TOPIC,
+                                                      mViolatedDirective.get());
+       NS_ENSURE_SUCCESS(rv, rv);
+ 
+       // 2) send reports for the policy that was violated
+-      mCSPContext->SendReports(mBlockedContentSource, mOriginalURI,
+-                               mViolatedDirective, mViolatedPolicyIndex,
+-                               mSourceFile, mScriptSample, mLineNum);
++      mCSPContext->SendReports(init, mViolatedPolicyIndex);
+ 
+       // 3) log to console (one per policy violation)
+       // mBlockedContentSource could be a URI or a string.
+       nsCOMPtr<nsIURI> blockedURI = do_QueryInterface(mBlockedContentSource);
+       // if mBlockedContentSource is not a URI, it could be a string
+       nsCOMPtr<nsISupportsCString> blockedString = do_QueryInterface(mBlockedContentSource);
+ 
+       nsCString blockedDataStr;
+@@ -1163,16 +1244,20 @@ class CSPReportSenderRunnable final : pu
+         nsString blockedDataChar16 = NS_ConvertUTF8toUTF16(blockedDataStr);
+         const char16_t* params[] = { mViolatedDirective.get(),
+                                      blockedDataChar16.get() };
+         mCSPContext->logToConsole(mReportOnlyFlag ? "CSPROViolationWithURI" :
+                                                     "CSPViolationWithURI",
+                                   params, ArrayLength(params), mSourceFile, mScriptSample,
+                                   mLineNum, 0, nsIScriptError::errorFlag);
+       }
++
++      // 4) fire violation event
++      mCSPContext->FireViolationEvent(init);
++
+       return NS_OK;
+     }
+ 
+   private:
+     nsCOMPtr<nsISupports>   mBlockedContentSource;
+     nsCOMPtr<nsIURI>        mOriginalURI;
+     uint32_t                mViolatedPolicyIndex;
+     bool                    mReportOnlyFlag;
+diff --git a/dom/security/nsCSPContext.h b/dom/security/nsCSPContext.h
+--- a/dom/security/nsCSPContext.h
++++ b/dom/security/nsCSPContext.h
+@@ -3,16 +3,17 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ #ifndef nsCSPContext_h___
+ #define nsCSPContext_h___
+ 
+ #include "mozilla/dom/nsCSPUtils.h"
++#include "mozilla/dom/SecurityPolicyViolationEvent.h"
+ #include "nsDataHashtable.h"
+ #include "nsIChannel.h"
+ #include "nsIChannelEventSink.h"
+ #include "nsIClassInfo.h"
+ #include "nsIContentSecurityPolicy.h"
+ #include "nsIInterfaceRequestor.h"
+ #include "nsISerializable.h"
+ #include "nsIStreamListener.h"
+@@ -53,23 +54,53 @@ class nsCSPContext : public nsIContentSe
+                       const char16_t** aParams,
+                       uint32_t aParamsLength,
+                       const nsAString& aSourceName,
+                       const nsAString& aSourceLine,
+                       uint32_t aLineNumber,
+                       uint32_t aColumnNumber,
+                       uint32_t aSeverityFlag);
+ 
+-    nsresult SendReports(nsISupports* aBlockedContentSource,
+-                         nsIURI* aOriginalURI,
+-                         nsAString& aViolatedDirective,
+-                         uint32_t aViolatedPolicyIndex,
+-                         nsAString& aSourceFile,
+-                         nsAString& aScriptSample,
+-                         uint32_t aLineNum);
++
++
++    /**
++     * Construct SecurityPolicyViolationEventInit structure.
++     *
++     * @param aBlockedContentSource
++     *        Either a CSP Source (like 'self', as string) or nsIURI: the source
++     *        of the violation.
++     * @param aOriginalUri
++     *        The original URI if the blocked content is a redirect, else null
++     * @param aViolatedDirective
++     *        the directive that was violated (string).
++     * @param aSourceFile
++     *        name of the file containing the inline script violation
++     * @param aScriptSample
++     *        a sample of the violating inline script
++     * @param aLineNum
++     *        source line number of the violation (if available)
++     * @param aViolationEventInit
++     *        The output
++     */
++    nsresult GatherSecurityPolicyViolationEventData(
++      nsISupports* aBlockedContentSource,
++      nsIURI* aOriginalURI,
++      nsAString& aViolatedDirective,
++      uint32_t aViolatedPolicyIndex,
++      nsAString& aSourceFile,
++      nsAString& aScriptSample,
++      uint32_t aLineNum,
++      mozilla::dom::SecurityPolicyViolationEventInit& aViolationEventInit);
++
++    nsresult SendReports(
++      const mozilla::dom::SecurityPolicyViolationEventInit& aViolationEventInit,
++      uint32_t aViolatedPolicyIndex);
++
++    nsresult FireViolationEvent(
++      const mozilla::dom::SecurityPolicyViolationEventInit& aViolationEventInit);
+ 
+     nsresult AsyncReportViolation(nsISupports* aBlockedContentSource,
+                                   nsIURI* aOriginalURI,
+                                   const nsAString& aViolatedDirective,
+                                   uint32_t aViolatedPolicyIndex,
+                                   const nsAString& aObserverSubject,
+                                   const nsAString& aSourceFile,
+                                   const nsAString& aScriptSample,
+diff --git a/dom/webidl/SecurityPolicyViolationEvent.webidl b/dom/webidl/SecurityPolicyViolationEvent.webidl
+new file mode 100644
+--- /dev/null
++++ b/dom/webidl/SecurityPolicyViolationEvent.webidl
+@@ -0,0 +1,41 @@
++/* 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/. */
++
++enum SecurityPolicyViolationEventDisposition
++{
++  "enforce", "report"
++};
++
++[Constructor(DOMString type, optional SecurityPolicyViolationEventInit eventInitDict)]
++interface SecurityPolicyViolationEvent : Event
++{
++    readonly attribute DOMString      documentURI;
++    readonly attribute DOMString      referrer;
++    readonly attribute DOMString      blockedURI;
++    readonly attribute DOMString      violatedDirective;
++    readonly attribute DOMString      effectiveDirective;
++    readonly attribute DOMString      originalPolicy;
++    readonly attribute DOMString      sourceFile;
++    readonly attribute DOMString      sample;
++    readonly attribute SecurityPolicyViolationEventDisposition disposition;
++    readonly attribute unsigned short statusCode;
++    readonly attribute long           lineNumber;
++    readonly attribute long           columnNumber;
++};
++
++dictionary SecurityPolicyViolationEventInit : EventInit
++{
++    DOMString      documentURI = "";
++    DOMString      referrer = "";
++    DOMString      blockedURI = "";
++    DOMString      violatedDirective = "";
++    DOMString      effectiveDirective = "";
++    DOMString      originalPolicy = "";
++    DOMString      sourceFile = "";
++    DOMString      sample = "";
++    SecurityPolicyViolationEventDisposition disposition = "report";
++    unsigned short statusCode = 0;
++    long           lineNumber = 0;
++    long           columnNumber = 0;
++};
+diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build
+--- a/dom/webidl/moz.build
++++ b/dom/webidl/moz.build
+@@ -1051,16 +1051,17 @@ GENERATED_EVENTS_WEBIDL_FILES = [
+     'PageTransitionEvent.webidl',
+     'PerformanceEntryEvent.webidl',
+     'PluginCrashedEvent.webidl',
+     'PopStateEvent.webidl',
+     'PopupBlockedEvent.webidl',
+     'ProgressEvent.webidl',
+     'PromiseRejectionEvent.webidl',
+     'ScrollViewChangeEvent.webidl',
++    'SecurityPolicyViolationEvent.webidl',
+     'StyleRuleChangeEvent.webidl',
+     'StyleSheetApplicableStateChangeEvent.webidl',
+     'StyleSheetChangeEvent.webidl',
+     'TCPServerSocketEvent.webidl',
+     'TCPSocketErrorEvent.webidl',
+     'TCPSocketEvent.webidl',
+     'TrackEvent.webidl',
+     'UDPMessageEvent.webidl',

+ 41 - 0
mozilla-release/patches/1037335-2-59a1.patch

@@ -0,0 +1,41 @@
+# HG changeset patch
+# User Chung-Sheng Fu <cfu@mozilla.com>
+# Date 1511967240 -7200
+# Node ID 207b671db6ec57f755ef5eeb0aab5307fb61b06f
+# Parent  2e7c128a01b81ccb230aec38e4b6a235c4d7f494
+Bug 1037335 - Add a mochitest for security policy violation event. r=ckerschb
+
+MozReview-Commit-ID: 7l5jJFEtIaT
+
+diff --git a/dom/security/test/csp/mochitest.ini b/dom/security/test/csp/mochitest.ini
+--- a/dom/security/test/csp/mochitest.ini
++++ b/dom/security/test/csp/mochitest.ini
+@@ -343,8 +343,9 @@ support-files =
+   file_spawn_shared_worker.js
+   file_spawn_service_worker.js
+ [test_frame_src.html]
+ support-files =
+   file_frame_src_frame_governs.html
+   file_frame_src_child_governs.html
+   file_frame_src.js
+   file_frame_src_inner.html
++[test_security_policy_violation_event.html]
+diff --git a/dom/security/test/csp/test_security_policy_violation_event.html b/dom/security/test/csp/test_security_policy_violation_event.html
+new file mode 100644
+--- /dev/null
++++ b/dom/security/test/csp/test_security_policy_violation_event.html
+@@ -0,0 +1,14 @@
++<!DOCTYPE html>
++<meta charset="utf-8">
++<meta http-equiv="Content-Security-Policy" content="img-src 'none'">
++<script src="/tests/SimpleTest/SimpleTest.js"></script>
++<script>
++SimpleTest.waitForExplicitFinish();
++document.addEventListener("securitypolicyviolation", (e) => {
++  SimpleTest.is(e.blockedURI, "http://mochi.test:8888/foo/bar.jpg", "blockedURI");
++  SimpleTest.todo_is(e.violatedDirective, "img-src", "violatedDirective")
++  SimpleTest.is(e.originalPolicy, "img-src 'none'", "originalPolicy");
++  SimpleTest.finish();
++});
++</script>
++<img src="http://mochi.test:8888/foo/bar.jpg">

+ 57 - 0
mozilla-release/patches/1037335-3no4or5-59a1.patch

@@ -0,0 +1,57 @@
+# HG changeset patch
+# User Chung-Sheng Fu <cfu@mozilla.com>
+# Date 1511967240 -7200
+# Node ID 0f09a387cbc4b093aa1535f75634cd1d1930f899
+# Parent  09ea70c5794ea57e4d5387ac068a6b12ff3c4dcc
+Bug 1037335 - Fix test failures. r=ckerschb,smaug
+
+Require review from DOM peer.
+
+MozReview-Commit-ID: HWBKKxxPh0e
+
+diff --git a/dom/events/test/test_all_synthetic_events.html b/dom/events/test/test_all_synthetic_events.html
+--- a/dom/events/test/test_all_synthetic_events.html
++++ b/dom/events/test/test_all_synthetic_events.html
+@@ -406,16 +406,20 @@ const kEventConstructors = {
+   WheelEvent:                                { create: function (aName, aProps) {
+                                                          return new WheelEvent(aName, aProps);
+                                                        },
+                                              },
+   WebGLContextEvent:                         { create: function (aName, aProps) {
+                                                          return new WebGLContextEvent(aName, aProps);
+                                                        },
+                                              },
++  SecurityPolicyViolationEvent:              { create: function (aName, aProps) {
++                                                         return new SecurityPolicyViolationEvent(aName, aProps);
++                                                       },
++                                             },
+ };
+ 
+ for (var name of Object.keys(kEventConstructors)) {
+   if (!kEventConstructors[name].chromeOnly) {
+     continue;
+   }
+   if (window[name]) {
+     ok(false, name + " should be chrome only.");
+diff --git a/dom/tests/mochitest/general/test_interfaces.js b/dom/tests/mochitest/general/test_interfaces.js
+--- a/dom/tests/mochitest/general/test_interfaces.js
++++ b/dom/tests/mochitest/general/test_interfaces.js
+@@ -810,16 +810,18 @@ var interfaceNamesInGlobalScope =
+     "Screen",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "ScreenOrientation",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "ScriptProcessorNode",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "ScrollAreaEvent",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
++    "SecurityPolicyViolationEvent",
++// IMPORTANT: Do not change this list without review from a DOM peer!
+     "Selection",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "ServiceWorker",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "ServiceWorkerContainer",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "ServiceWorkerRegistration",
+ // IMPORTANT: Do not change this list without review from a DOM peer!

+ 158 - 0
mozilla-release/patches/1037335-6-59a1.patch

@@ -0,0 +1,158 @@
+# HG changeset patch
+# User Chung-Sheng Fu <cfu@mozilla.com>
+# Date 1511967300 -7200
+# Node ID 3f2598dad67c2ed8c521ce68c8f383385a2a088f
+# Parent  c1257a5e7e4446e43ca81d6278715b7ad8b0b8f7
+Bug 1037335 - Add a pref to enable only within Nightly and Early Beta. r=ckerschb,smaug
+
+MozReview-Commit-ID: Bi82dHm53qX
+
+diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp
+--- a/dom/security/nsCSPContext.cpp
++++ b/dom/security/nsCSPContext.cpp
+@@ -268,28 +268,31 @@ NS_IMPL_CLASSINFO(nsCSPContext,
+                   nsIClassInfo::MAIN_THREAD_ONLY,
+                   NS_CSPCONTEXT_CID)
+ 
+ NS_IMPL_ISUPPORTS_CI(nsCSPContext,
+                      nsIContentSecurityPolicy,
+                      nsISerializable)
+ 
+ int32_t nsCSPContext::sScriptSampleMaxLength;
++bool nsCSPContext::sViolationEventsEnabled = false;
+ 
+ nsCSPContext::nsCSPContext()
+   : mInnerWindowID(0)
+   , mLoadingContext(nullptr)
+   , mLoadingPrincipal(nullptr)
+   , mQueueUpMessages(true)
+ {
+   static bool sInitialized = false;
+   if (!sInitialized) {
+     Preferences::AddIntVarCache(&sScriptSampleMaxLength,
+                                 "security.csp.reporting.script-sample.max-length",
+                                 40);
++    Preferences::AddBoolVarCache(&sViolationEventsEnabled,
++                                 "security.csp.enable_violation_events");
+     sInitialized = true;
+   }
+ 
+   CSPCONTEXTLOG(("nsCSPContext::nsCSPContext"));
+ }
+ 
+ nsCSPContext::~nsCSPContext()
+ {
+@@ -1132,16 +1135,20 @@ nsCSPContext::SendReports(
+   }
+   return NS_OK;
+ }
+ 
+ nsresult
+ nsCSPContext::FireViolationEvent(
+   const mozilla::dom::SecurityPolicyViolationEventInit& aViolationEventInit)
+ {
++  if (!sViolationEventsEnabled) {
++    return NS_OK;
++  }
++
+   nsCOMPtr<nsIDocument> doc = do_QueryReferent(mLoadingContext);
+   if (!doc) {
+     return NS_OK;
+   }
+ 
+   RefPtr<mozilla::dom::Event> event =
+     mozilla::dom::SecurityPolicyViolationEvent::Constructor(
+       doc,
+diff --git a/dom/security/nsCSPContext.h b/dom/security/nsCSPContext.h
+--- a/dom/security/nsCSPContext.h
++++ b/dom/security/nsCSPContext.h
+@@ -139,16 +139,18 @@ class nsCSPContext : public nsIContentSe
+ 
+     static int32_t sScriptSampleMaxLength;
+ 
+     static uint32_t ScriptSampleMaxLength()
+     {
+       return std::max(sScriptSampleMaxLength, 0);
+     }
+ 
++    static bool sViolationEventsEnabled;
++
+     nsString                                   mReferrer;
+     uint64_t                                   mInnerWindowID; // used for web console logging
+     nsTArray<nsCSPPolicy*>                     mPolicies;
+     nsCOMPtr<nsIURI>                           mSelfURI;
+     nsDataHashtable<nsCStringHashKey, int16_t> mShouldLoadCache;
+     nsCOMPtr<nsILoadGroup>                     mCallingChannelLoadGroup;
+     nsWeakPtr                                  mLoadingContext;
+     // The CSP hangs off the principal, so let's store a raw pointer of the principal
+diff --git a/dom/security/test/csp/test_security_policy_violation_event.html b/dom/security/test/csp/test_security_policy_violation_event.html
+--- a/dom/security/test/csp/test_security_policy_violation_event.html
++++ b/dom/security/test/csp/test_security_policy_violation_event.html
+@@ -1,14 +1,19 @@
+ <!DOCTYPE html>
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Security-Policy" content="img-src 'none'">
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script>
+ SimpleTest.waitForExplicitFinish();
++SpecialPowers.pushPrefEnv({
++  set: [
++    ["security.csp.enable_violation_events", true]
++  ]
++});
+ document.addEventListener("securitypolicyviolation", (e) => {
+   SimpleTest.is(e.blockedURI, "http://mochi.test:8888/foo/bar.jpg", "blockedURI");
+   SimpleTest.todo_is(e.violatedDirective, "img-src", "violatedDirective")
+   SimpleTest.is(e.originalPolicy, "img-src 'none'", "originalPolicy");
+   SimpleTest.finish();
+ });
+ </script>
+ <img src="http://mochi.test:8888/foo/bar.jpg">
+diff --git a/dom/webidl/SecurityPolicyViolationEvent.webidl b/dom/webidl/SecurityPolicyViolationEvent.webidl
+--- a/dom/webidl/SecurityPolicyViolationEvent.webidl
++++ b/dom/webidl/SecurityPolicyViolationEvent.webidl
+@@ -2,17 +2,18 @@
+  * 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/. */
+ 
+ enum SecurityPolicyViolationEventDisposition
+ {
+   "enforce", "report"
+ };
+ 
+-[Constructor(DOMString type, optional SecurityPolicyViolationEventInit eventInitDict)]
++[Constructor(DOMString type, optional SecurityPolicyViolationEventInit eventInitDict),
++ Pref="security.csp.enable_violation_events"]
+ interface SecurityPolicyViolationEvent : Event
+ {
+     readonly attribute DOMString      documentURI;
+     readonly attribute DOMString      referrer;
+     readonly attribute DOMString      blockedURI;
+     readonly attribute DOMString      violatedDirective;
+     readonly attribute DOMString      effectiveDirective;
+     readonly attribute DOMString      originalPolicy;
+diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
+--- a/modules/libpref/init/all.js
++++ b/modules/libpref/init/all.js
+@@ -2627,16 +2627,21 @@ pref("security.checkloaduri", true);
+ pref("security.xpconnect.plugin.unrestricted", true);
+ // security-sensitive dialogs should delay button enabling. In milliseconds.
+ pref("security.dialog_enable_delay", 1000);
+ pref("security.notification_enable_delay", 500);
+ 
+ pref("security.csp.enable", true);
+ pref("security.csp.experimentalEnabled", false);
+ pref("security.csp.enableStrictDynamic", true);
++#ifdef EARLY_BETA_OR_EARLIER
++pref("security.csp.enable_violation_events", true);
++#else
++pref("security.csp.enable_violation_events", false);
++#endif
+ 
+ // Default Content Security Policy to apply to signed contents.
+ pref("security.signed_content.CSP.default", "script-src 'self'; style-src 'self'");
+ 
+ // Mixed content blocking
+ pref("security.mixed_content.block_active_content", false);
+ pref("security.mixed_content.block_display_content", false);
+ 

+ 42 - 0
mozilla-release/patches/1403866-58a1.patch

@@ -0,0 +1,42 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1506669658 -7200
+# Node ID c5e45bf14e9ab27b9cedac2b47d96bdb3725f3ca
+# Parent  de4e28c5c4a64a3aef78180b58b4bd7f27b8f05b
+Bug 1403866 - No AutoSafeJSContext in Console.cpp, r=bz
+
+diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp
+--- a/dom/console/Console.cpp
++++ b/dom/console/Console.cpp
+@@ -397,25 +397,28 @@ protected:
+ 
+     WorkerPrivate* wp = mWorkerPrivate;
+     while (wp->GetParent()) {
+       wp = wp->GetParent();
+     }
+ 
+     MOZ_ASSERT(!wp->GetWindow());
+ 
+-    AutoSafeJSContext cx;
++    AutoJSAPI jsapi;
++    jsapi.Init();
++
++    JSContext* cx = jsapi.cx();
+ 
+     JS::Rooted<JSObject*> global(cx, mConsole->GetOrCreateSandbox(cx, wp->GetPrincipal()));
+     if (NS_WARN_IF(!global)) {
+       return;
+     }
+ 
+-    // The CreateSandbox call returns a proxy to the actual sandbox object. We
+-    // don't need a proxy here.
++    // The GetOrCreateSandbox call returns a proxy to the actual sandbox object.
++    // We don't need a proxy here.
+     global = js::UncheckedUnwrap(global);
+ 
+     JSAutoCompartment ac(cx, global);
+ 
+     RunConsole(cx, nullptr, nullptr);
+   }
+ 
+   void

+ 393 - 0
mozilla-release/patches/1418243-1no2-59a1.patch

@@ -0,0 +1,393 @@
+# HG changeset patch
+# User Chung-Sheng Fu <cfu@mozilla.com>
+# Date 1516136340 -7200
+# Node ID 25fd1d8d42b47c72493fdabcdb27c5a1708a01ad
+# Parent  547a545b73356f940b0e0bd5067c328066061d98
+Bug 1418243 - Fix SecurityPolicyViolationEvent.violatedDirective. r=ckerschb
+
+MozReview-Commit-ID: 8DQ7CI5exUL
+
+diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp
+--- a/dom/security/nsCSPContext.cpp
++++ b/dom/security/nsCSPContext.cpp
+@@ -1,14 +1,17 @@
+ /* -*- 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 <string>
++#include <unordered_set>
++
+ #include "nsCOMPtr.h"
+ #include "nsContentPolicyUtils.h"
+ #include "nsContentUtils.h"
+ #include "nsCSPContext.h"
+ #include "nsCSPParser.h"
+ #include "nsCSPService.h"
+ #include "nsError.h"
+ #include "nsIAsyncVerifyRedirectCallback.h"
+@@ -59,16 +62,39 @@ GetCspContextLog()
+   return gCspContextPRLog;
+ }
+ 
+ #define CSPCONTEXTLOG(args) MOZ_LOG(GetCspContextLog(), mozilla::LogLevel::Debug, args)
+ #define CSPCONTEXTLOGENABLED() MOZ_LOG_TEST(GetCspContextLog(), mozilla::LogLevel::Debug)
+ 
+ static const uint32_t CSP_CACHE_URI_CUTOFF_SIZE = 512;
+ 
++#ifdef DEBUG
++/**
++ * This function is only used for verification purposes within
++ * GatherSecurityPolicyViolationEventData.
++ */
++static bool
++ValidateDirectiveName(const nsAString& aDirective)
++{
++  static const auto directives = [] () {
++    std::unordered_set<std::string> directives;
++    constexpr size_t dirLen = sizeof(CSPStrDirectives) / sizeof(CSPStrDirectives[0]);
++    for (size_t i = 0; i < dirLen; ++i) {
++      directives.insert(CSPStrDirectives[i]);
++    }
++    return directives;
++  } ();
++
++  nsAutoString directive(aDirective);
++  auto itr = directives.find(NS_ConvertUTF16toUTF8(directive).get());
++  return itr != directives.end();
++}
++#endif // DEBUG
++
+ /**
+  * Creates a key for use in the ShouldLoad cache.
+  * Looks like: <uri>!<nsIContentPolicy::LOAD_TYPE>
+  */
+ nsresult
+ CreateCacheKey_Internal(nsIURI* aContentLocation,
+                         nsContentPolicyType aContentType,
+                         nsACString& outCacheKey)
+@@ -864,16 +890,18 @@ nsCSPContext::GatherSecurityPolicyViolat
+   uint32_t aViolatedPolicyIndex,
+   nsAString& aSourceFile,
+   nsAString& aScriptSample,
+   uint32_t aLineNum,
+   mozilla::dom::SecurityPolicyViolationEventInit& aViolationEventInit)
+ {
+   NS_ENSURE_ARG_MAX(aViolatedPolicyIndex, mPolicies.Length() - 1);
+ 
++  MOZ_ASSERT(ValidateDirectiveName(aViolatedDirective), "Invalid directive name");
++
+   nsresult rv;
+ 
+   // document-uri
+   nsAutoCString reportDocumentURI;
+   StripURIForReporting(mSelfURI, mSelfURI, reportDocumentURI);
+   aViolationEventInit.mDocumentURI = NS_ConvertUTF8toUTF16(reportDocumentURI);
+ 
+   // referrer
+@@ -895,21 +923,24 @@ nsCSPContext::GatherSecurityPolicyViolat
+     if (reportBlockedURI.IsEmpty()) {
+       // this can happen for frame-ancestors violation where the violating
+       // ancestor is cross-origin.
+       NS_WARNING("No blocked URI (null aBlockedContentSource) for CSP violation report.");
+     }
+     aViolationEventInit.mBlockedURI = NS_ConvertUTF8toUTF16(reportBlockedURI);
+   }
+ 
+-  // violated-directive
+-  aViolationEventInit.mViolatedDirective = aViolatedDirective;
++  // effective-directive
++  // The name of the policy directive that was violated.
++  aViolationEventInit.mEffectiveDirective = aViolatedDirective;
+ 
+-  // effective-directive
+-  aViolationEventInit.mEffectiveDirective = aViolatedDirective;
++  // violated-directive
++  // In CSP2, the policy directive that was violated, as it appears in the policy.
++  // In CSP3, the same as effective-directive.
++  aViolationEventInit.mViolatedDirective = aViolatedDirective;
+ 
+   // original-policy
+   nsAutoString originalPolicy;
+   rv = this->GetPolicyString(aViolatedPolicyIndex, originalPolicy);
+   NS_ENSURE_SUCCESS(rv, rv);
+   aViolationEventInit.mOriginalPolicy = originalPolicy;
+ 
+   // source-file
+@@ -1211,28 +1242,31 @@ class CSPReportSenderRunnable final : pu
+         mObserverSubject = do_QueryInterface(supportscstr);
+       }
+     }
+ 
+     NS_IMETHOD Run() override
+     {
+       MOZ_ASSERT(NS_IsMainThread());
+ 
++      nsresult rv;
++
+       // 0) prepare violation data
+       mozilla::dom::SecurityPolicyViolationEventInit init;
+-      mCSPContext->GatherSecurityPolicyViolationEventData(
++      rv = mCSPContext->GatherSecurityPolicyViolationEventData(
+         mBlockedContentSource, mOriginalURI,
+         mViolatedDirective, mViolatedPolicyIndex,
+         mSourceFile, mScriptSample, mLineNum,
+         init);
++      NS_ENSURE_SUCCESS(rv, rv);
+ 
+       // 1) notify observers
+       nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
+       NS_ASSERTION(observerService, "needs observer service");
+-      nsresult rv = observerService->NotifyObservers(mObserverSubject,
++      rv = observerService->NotifyObservers(mObserverSubject,
+                                                      CSP_VIOLATION_TOPIC,
+                                                      mViolatedDirective.get());
+       NS_ENSURE_SUCCESS(rv, rv);
+ 
+       // 2) send reports for the policy that was violated
+       mCSPContext->SendReports(init, mViolatedPolicyIndex);
+ 
+       // 3) log to console (one per policy violation)
+diff --git a/dom/security/nsCSPUtils.cpp b/dom/security/nsCSPUtils.cpp
+--- a/dom/security/nsCSPUtils.cpp
++++ b/dom/security/nsCSPUtils.cpp
+@@ -1241,16 +1241,22 @@ nsCSPDirective::visitSrcs(nsCSPSrcVisito
+   return true;
+ }
+ 
+ bool nsCSPDirective::equals(CSPDirective aDirective) const
+ {
+   return (mDirective == aDirective);
+ }
+ 
++void
++nsCSPDirective::getDirName(nsAString& outStr) const
++{
++  outStr.AppendASCII(CSP_CSPDirectiveToString(mDirective));
++}
++
+ /* =============== nsCSPChildSrcDirective ============= */
+ 
+ nsCSPChildSrcDirective::nsCSPChildSrcDirective(CSPDirective aDirective)
+   : nsCSPDirective(aDirective)
+   , mRestrictFrames(false)
+   , mRestrictWorkers(false)
+ {
+ }
+@@ -1326,16 +1332,23 @@ nsBlockAllMixedContentDirective::~nsBloc
+ 
+ void
+ nsBlockAllMixedContentDirective::toString(nsAString& outStr) const
+ {
+   outStr.AppendASCII(CSP_CSPDirectiveToString(
+     nsIContentSecurityPolicy::BLOCK_ALL_MIXED_CONTENT));
+ }
+ 
++void
++nsBlockAllMixedContentDirective::getDirName(nsAString& outStr) const
++{
++  outStr.AppendASCII(CSP_CSPDirectiveToString(
++    nsIContentSecurityPolicy::BLOCK_ALL_MIXED_CONTENT));
++}
++
+ /* =============== nsUpgradeInsecureDirective ============= */
+ 
+ nsUpgradeInsecureDirective::nsUpgradeInsecureDirective(CSPDirective aDirective)
+ : nsCSPDirective(aDirective)
+ {
+ }
+ 
+ nsUpgradeInsecureDirective::~nsUpgradeInsecureDirective()
+@@ -1344,16 +1357,23 @@ nsUpgradeInsecureDirective::~nsUpgradeIn
+ 
+ void
+ nsUpgradeInsecureDirective::toString(nsAString& outStr) const
+ {
+   outStr.AppendASCII(CSP_CSPDirectiveToString(
+     nsIContentSecurityPolicy::UPGRADE_IF_INSECURE_DIRECTIVE));
+ }
+ 
++void
++nsUpgradeInsecureDirective::getDirName(nsAString& outStr) const
++{
++  outStr.AppendASCII(CSP_CSPDirectiveToString(
++    nsIContentSecurityPolicy::UPGRADE_IF_INSECURE_DIRECTIVE));
++}
++
+ /* ===== nsRequireSRIForDirective ========================= */
+ 
+ nsRequireSRIForDirective::nsRequireSRIForDirective(CSPDirective aDirective)
+ : nsCSPDirective(aDirective)
+ {
+ }
+ 
+ nsRequireSRIForDirective::~nsRequireSRIForDirective()
+@@ -1395,16 +1415,23 @@ nsRequireSRIForDirective::restrictsConte
+ bool
+ nsRequireSRIForDirective::allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
+                                  bool aParserCreated) const
+ {
+   // can only disallow CSP_REQUIRE_SRI_FOR.
+   return (aKeyword != CSP_REQUIRE_SRI_FOR);
+ }
+ 
++void
++nsRequireSRIForDirective::getDirName(nsAString& outStr) const
++{
++  outStr.AppendASCII(CSP_CSPDirectiveToString(
++    nsIContentSecurityPolicy::REQUIRE_SRI_FOR));
++}
++
+ /* ===== nsCSPPolicy ========================= */
+ 
+ nsCSPPolicy::nsCSPPolicy()
+   : mUpgradeInsecDir(nullptr)
+   , mReportOnly(false)
+ {
+   CSPUTILSLOG(("nsCSPPolicy::nsCSPPolicy"));
+ }
+@@ -1448,32 +1475,32 @@ nsCSPPolicy::permits(CSPDirective aDir,
+   nsCSPDirective* defaultDir = nullptr;
+ 
+   // Try to find a relevant directive
+   // These directive arrays are short (1-5 elements), not worth using a hashtable.
+   for (uint32_t i = 0; i < mDirectives.Length(); i++) {
+     if (mDirectives[i]->equals(aDir)) {
+       if (!mDirectives[i]->permits(aUri, aNonce, aWasRedirected, mReportOnly,
+                                    mUpgradeInsecDir, aParserCreated)) {
+-        mDirectives[i]->toString(outViolatedDirective);
++        mDirectives[i]->getDirName(outViolatedDirective);
+         return false;
+       }
+       return true;
+     }
+     if (mDirectives[i]->isDefaultDirective()) {
+       defaultDir = mDirectives[i];
+     }
+   }
+ 
+   // If the above loop runs through, we haven't found a matching directive.
+   // Avoid relooping, just store the result of default-src while looping.
+   if (!aSpecific && defaultDir) {
+     if (!defaultDir->permits(aUri, aNonce, aWasRedirected, mReportOnly,
+                              mUpgradeInsecDir, aParserCreated)) {
+-      defaultDir->toString(outViolatedDirective);
++      defaultDir->getDirName(outViolatedDirective);
+       return false;
+     }
+     return true;
+   }
+ 
+   // Nothing restricts this, so we're allowing the load
+   // See bug 764937
+   return true;
+@@ -1590,27 +1617,27 @@ nsCSPPolicy::hasDirective(CSPDirective a
+  */
+ void
+ nsCSPPolicy::getDirectiveStringForContentType(nsContentPolicyType aContentType,
+                                               nsAString& outDirective) const
+ {
+   nsCSPDirective* defaultDir = nullptr;
+   for (uint32_t i = 0; i < mDirectives.Length(); i++) {
+     if (mDirectives[i]->restrictsContentType(aContentType)) {
+-      mDirectives[i]->toString(outDirective);
++      mDirectives[i]->getDirName(outDirective);
+       return;
+     }
+     if (mDirectives[i]->isDefaultDirective()) {
+       defaultDir = mDirectives[i];
+     }
+   }
+   // if we haven't found a matching directive yet,
+   // the contentType must be restricted by the default directive
+   if (defaultDir) {
+-    defaultDir->toString(outDirective);
++    defaultDir->getDirName(outDirective);
+     return;
+   }
+   NS_ASSERTION(false, "Can not query directive string for contentType!");
+   outDirective.AppendASCII("couldNotQueryViolatedDirective");
+ }
+ 
+ void
+ nsCSPPolicy::getDirectiveAsString(CSPDirective aDir, nsAString& outDirective) const
+diff --git a/dom/security/nsCSPUtils.h b/dom/security/nsCSPUtils.h
+--- a/dom/security/nsCSPUtils.h
++++ b/dom/security/nsCSPUtils.h
+@@ -466,16 +466,18 @@ class nsCSPDirective {
+      { return mDirective == nsIContentSecurityPolicy::DEFAULT_SRC_DIRECTIVE; }
+ 
+     virtual bool equals(CSPDirective aDirective) const;
+ 
+     void getReportURIs(nsTArray<nsString> &outReportURIs) const;
+ 
+     bool visitSrcs(nsCSPSrcVisitor* aVisitor) const;
+ 
++    virtual void getDirName(nsAString& outStr) const;
++
+   protected:
+     CSPDirective            mDirective;
+     nsTArray<nsCSPBaseSrc*> mSrcs;
+ };
+ 
+ /* =============== nsCSPChildSrcDirective ============= */
+ 
+ /*
+@@ -544,16 +546,18 @@ class nsBlockAllMixedContentDirective : 
+     bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
+                 bool aParserCreated) const override
+       { return false; }
+ 
+     void toString(nsAString& outStr) const override;
+ 
+     void addSrcs(const nsTArray<nsCSPBaseSrc*>& aSrcs) override
+       {  MOZ_ASSERT(false, "block-all-mixed-content does not hold any srcs"); }
++
++    void getDirName(nsAString& outStr) const override;
+ };
+ 
+ /* =============== nsUpgradeInsecureDirective === */
+ 
+ /*
+  * Upgrading insecure requests includes the following actors:
+  * (1) CSP:
+  *     The CSP implementation whitelists the http-request
+@@ -597,16 +601,18 @@ class nsUpgradeInsecureDirective : publi
+     bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
+                 bool aParserCreated) const override
+       { return false; }
+ 
+     void toString(nsAString& outStr) const override;
+ 
+     void addSrcs(const nsTArray<nsCSPBaseSrc*>& aSrcs) override
+       {  MOZ_ASSERT(false, "upgrade-insecure-requests does not hold any srcs"); }
++
++    void getDirName(nsAString& outStr) const override;
+ };
+ 
+ /* ===== nsRequireSRIForDirective ========================= */
+ 
+ class nsRequireSRIForDirective : public nsCSPDirective {
+   public:
+     explicit nsRequireSRIForDirective(CSPDirective aDirective);
+     ~nsRequireSRIForDirective();
+@@ -614,16 +620,17 @@ class nsRequireSRIForDirective : public 
+     void toString(nsAString& outStr) const override;
+ 
+     void addType(nsContentPolicyType aType)
+       { mTypes.AppendElement(aType); }
+     bool hasType(nsContentPolicyType aType) const;
+     bool restrictsContentType(nsContentPolicyType aType) const override;
+     bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
+                 bool aParserCreated) const override;
++    void getDirName(nsAString& outStr) const override;
+ 
+   private:
+     nsTArray<nsContentPolicyType> mTypes;
+ };
+ 
+ /* =============== nsCSPPolicy ================== */
+ 
+ class nsCSPPolicy {

+ 194 - 0
mozilla-release/patches/1418243-3-59a1.patch

@@ -0,0 +1,194 @@
+# HG changeset patch
+# User Chung-Sheng Fu <cfu@mozilla.com>
+# Date 1516136400 -7200
+# Node ID a1752a8ab7a040da7807d33d5bda0c07721a33d2
+# Parent  222a9d613f1b2ad07faa123b5dc43b4799457349
+Bug 1418243 - Fix mochitest failures due to violationDirective change. r=ckerschb
+
+MozReview-Commit-ID: AphtAxYo6Hr
+
+diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_cspro.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_cspro.js
+--- a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_cspro.js
++++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_cspro.js
+@@ -16,21 +16,21 @@ See Bug 1010953.
+ 
+ "use strict";
+ 
+ const TEST_URI = "data:text/html;charset=utf8,Web Console CSP report only test";
+ const TEST_VIOLATION = "http://example.com/browser/devtools/client/webconsole/" +
+                        "new-console-output/test/mochitest/test-cspro.html";
+ const CSP_VIOLATION_MSG =
+   "Content Security Policy: The page\u2019s settings blocked the loading of a resource " +
+-  "at http://some.example.com/cspro.png (\u201cimg-src http://example.com\u201d).";
++  "at http://some.example.com/cspro.png (\u201cimg-src\u201d).";
+ const CSP_REPORT_MSG =
+   "Content Security Policy: The page\u2019s settings observed the loading of a " +
+   "resource at http://some.example.com/cspro.js " +
+-  "(\u201cscript-src http://example.com\u201d). A CSP report is being sent.";
++  "(\u201cscript-src\u201d). A CSP report is being sent.";
+ 
+ add_task(async function () {
+   let hud = await openNewTabAndConsole(TEST_URI);
+ 
+   let onCspViolationMessage = waitForMessage(hud, CSP_VIOLATION_MSG, ".message.error");
+   let onCspReportMessage = waitForMessage(hud, CSP_REPORT_MSG, ".message.error");
+ 
+   info("Load a page with CSP warnings.");
+diff --git a/devtools/client/webconsole/test/browser_webconsole_bug_1010953_cspro.js b/devtools/client/webconsole/test/browser_webconsole_bug_1010953_cspro.js
+--- a/devtools/client/webconsole/test/browser_webconsole_bug_1010953_cspro.js
++++ b/devtools/client/webconsole/test/browser_webconsole_bug_1010953_cspro.js
+@@ -18,21 +18,21 @@ CSP_REPORT_MSG are confirmed to be found
+ 
+ const TEST_URI = "data:text/html;charset=utf8,Web Console CSP report only " +
+                  "test (bug 1010953)";
+ const TEST_VIOLATION = "http://example.com/browser/devtools/client/" +
+                        "webconsole/test/test_bug_1010953_cspro.html";
+ const CSP_VIOLATION_MSG = "Content Security Policy: The page\u2019s settings " +
+                           "blocked the loading of a resource at " +
+                           "http://some.example.com/test.png " +
+-                          "(\u201cimg-src http://example.com\u201d).";
++                          "(\u201cimg-src\u201d).";
+ const CSP_REPORT_MSG = "Content Security Policy: The page\u2019s settings " +
+                        "observed the loading of a resource at " +
+                        "http://some.example.com/test_bug_1010953_cspro.js " +
+-                       "(\u201cscript-src http://example.com\u201d). A CSP report is " +
++                       "(\u201cscript-src\u201d). A CSP report is " +
+                        "being sent.";
+ 
+ add_task(function* () {
+   let { browser } = yield loadTab(TEST_URI);
+ 
+   let hud = yield openConsole();
+ 
+   hud.jsterm.clearOutput();
+diff --git a/devtools/client/webconsole/test/browser_webconsole_bug_1247459_violation.js b/devtools/client/webconsole/test/browser_webconsole_bug_1247459_violation.js
+--- a/devtools/client/webconsole/test/browser_webconsole_bug_1247459_violation.js
++++ b/devtools/client/webconsole/test/browser_webconsole_bug_1247459_violation.js
+@@ -8,18 +8,17 @@
+ 
+ "use strict";
+ 
+ const TEST_URI = "data:text/html;charset=utf8,Web Console CSP violation test";
+ const TEST_VIOLATION = "https://example.com/browser/devtools/client/" +
+                        "webconsole/test/test_bug_1247459_violation.html";
+ const CSP_VIOLATION_MSG = "Content Security Policy: The page\u2019s settings " +
+                           "blocked the loading of a resource at " +
+-                          "http://some.example.com/test.png (\u201cimg-src " +
+-                          "https://example.com\u201d).";
++                          "http://some.example.com/test.png (\u201cimg-src\u201d).";
+ 
+ add_task(function* () {
+   let { browser } = yield loadTab(TEST_URI);
+ 
+   let hud = yield openConsole();
+ 
+   hud.jsterm.clearOutput();
+ 
+diff --git a/devtools/client/webconsole/test/browser_webconsole_bug_770099_violation.js b/devtools/client/webconsole/test/browser_webconsole_bug_770099_violation.js
+--- a/devtools/client/webconsole/test/browser_webconsole_bug_770099_violation.js
++++ b/devtools/client/webconsole/test/browser_webconsole_bug_770099_violation.js
+@@ -7,18 +7,17 @@
+ 
+ "use strict";
+ 
+ const TEST_URI = "data:text/html;charset=utf8,Web Console CSP violation test";
+ const TEST_VIOLATION = "https://example.com/browser/devtools/client/" +
+                        "webconsole/test/test_bug_770099_violation.html";
+ const CSP_VIOLATION_MSG = "Content Security Policy: The page\u2019s settings " +
+                           "blocked the loading of a resource at " +
+-                          "http://some.example.com/test.png (\u201cdefault-src " +
+-                          "https://example.com\u201d).";
++                          "http://some.example.com/test.png (\u201cdefault-src\u201d).";
+ 
+ add_task(function* () {
+   let { browser } = yield loadTab(TEST_URI);
+ 
+   let hud = yield openConsole();
+ 
+   hud.jsterm.clearOutput();
+ 
+diff --git a/dom/security/test/csp/test_frame_ancestors_ro.html b/dom/security/test/csp/test_frame_ancestors_ro.html
+--- a/dom/security/test/csp/test_frame_ancestors_ro.html
++++ b/dom/security/test/csp/test_frame_ancestors_ro.html
+@@ -18,17 +18,17 @@ let testResults = {
+ 
+ function checkResults(reportObj) {
+   let cspReport = reportObj["csp-report"];
+   is(cspReport["document-uri"], docUri, "Incorrect document-uri");
+ 
+   // we can not test for the whole referrer since it includes platform specific information
+   is(cspReport["referrer"], document.location.toString(), "Incorrect referrer");
+   is(cspReport["blocked-uri"], document.location.toString(), "Incorrect blocked-uri");
+-  is(cspReport["violated-directive"], "frame-ancestors 'none'", "Incorrect violated-directive");
++  is(cspReport["violated-directive"], "frame-ancestors", "Incorrect violated-directive");
+   is(cspReport["original-policy"], "frame-ancestors 'none'; report-uri http://mochi.test:8888/foo.sjs", "Incorrect original-policy");
+   testResults.reportFired = true;
+ }
+ 
+ let chromeScriptUrl = SimpleTest.getTestFileURL("file_report_chromescript.js");
+ let script = SpecialPowers.loadChromeScript(chromeScriptUrl);
+ 
+ script.addMessageListener('opening-request-completed', function ml(msg) {
+diff --git a/dom/security/test/csp/test_report.html b/dom/security/test/csp/test_report.html
+--- a/dom/security/test/csp/test_report.html
++++ b/dom/security/test/csp/test_report.html
+@@ -45,17 +45,17 @@ window.checkResults = function(reportObj
+   is(cspReport["document-uri"], docUri, "Incorrect document-uri");
+ 
+   // we can not test for the whole referrer since it includes platform specific information
+   ok(cspReport["referrer"].startsWith("http://mochi.test:8888/tests/dom/security/test/csp/test_report.html"),
+      "Incorrect referrer");
+ 
+   is(cspReport["blocked-uri"], "self", "Incorrect blocked-uri");
+ 
+-  is(cspReport["violated-directive"], "default-src 'none'", "Incorrect violated-directive");
++  is(cspReport["violated-directive"], "default-src", "Incorrect violated-directive");
+ 
+   is(cspReport["original-policy"], "default-src 'none'; report-uri http://mochi.test:8888/foo.sjs",
+      "Incorrect original-policy");
+ 
+   is(cspReport["source-file"], docUri, "Incorrect source-file");
+ 
+   is(cspReport["script-sample"], "\n    var foo = \"propEscFoo\";\n    var bar...",
+      "Incorrect script-sample");
+diff --git a/dom/security/test/csp/test_report_for_import.html b/dom/security/test/csp/test_report_for_import.html
+--- a/dom/security/test/csp/test_report_for_import.html
++++ b/dom/security/test/csp/test_report_for_import.html
+@@ -45,17 +45,17 @@ function checkResults(reportStr) {
+     var reportObj = JSON.parse(reportStr);
+     var cspReport = reportObj["csp-report"];
+ 
+     is(cspReport["document-uri"], DOC_URI, "Incorrect document-uri");
+     is(cspReport["referrer"],
+        "http://mochi.test:8888/tests/dom/security/test/csp/test_report_for_import.html",
+        "Incorrect referrer");
+     is(cspReport["violated-directive"],
+-       "style-src http://mochi.test:8888",
++       "style-src",
+        "Incorrect violated-directive");
+     is(cspReport["original-policy"],
+        "style-src http://mochi.test:8888; report-uri " +
+        "http://mochi.test:8888/tests/dom/security/test/csp/file_report_for_import_server.sjs?report",
+        "Incorrect original-policy");
+     is(cspReport["blocked-uri"],
+        "http://example.com",
+        "Incorrect blocked-uri");
+diff --git a/dom/security/test/csp/test_security_policy_violation_event.html b/dom/security/test/csp/test_security_policy_violation_event.html
+--- a/dom/security/test/csp/test_security_policy_violation_event.html
++++ b/dom/security/test/csp/test_security_policy_violation_event.html
+@@ -6,14 +6,14 @@
+ SimpleTest.waitForExplicitFinish();
+ SpecialPowers.pushPrefEnv({
+   set: [
+     ["security.csp.enable_violation_events", true]
+   ]
+ });
+ document.addEventListener("securitypolicyviolation", (e) => {
+   SimpleTest.is(e.blockedURI, "http://mochi.test:8888/foo/bar.jpg", "blockedURI");
+-  SimpleTest.todo_is(e.violatedDirective, "img-src", "violatedDirective")
++  SimpleTest.is(e.violatedDirective, "img-src", "violatedDirective")
+   SimpleTest.is(e.originalPolicy, "img-src 'none'", "originalPolicy");
+   SimpleTest.finish();
+ });
+ </script>
+ <img src="http://mochi.test:8888/foo/bar.jpg">

+ 676 - 0
mozilla-release/patches/1425574-1-59a1.patch

@@ -0,0 +1,676 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1515089983 -3600
+# Node ID e6a832b492dd99ce7d41dca8b6f797b150558344
+# Parent  8445cc9c1806b1e4876ba4a9f760d34b92175535
+Bug 1425574 - Fill the feature gap between Console.jsm and Console API - part 1 - Console.createInstance(), r=smaug
+
+diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf
+--- a/dom/bindings/Bindings.conf
++++ b/dom/bindings/Bindings.conf
+@@ -162,16 +162,20 @@ DOMInterfaces = {
+     'nativeType': 'mozilla::dom::workers::ServiceWorkerClients',
+     'headerFile': 'mozilla/dom/workers/bindings/ServiceWorkerClients.h',
+ },
+ 
+ 'console': {
+     'nativeType': 'mozilla::dom::Console',
+ },
+ 
++'ConsoleInstance': {
++    'implicitJSContext': ['clear', 'count', 'groupEnd', 'time', 'timeEnd'],
++},
++
+ 'ConvolverNode': {
+     'implicitJSContext': [ 'buffer' ],
+ },
+ 
+ 'Coordinates': {
+     'headerFile': 'nsGeoPosition.h'
+ },
+ 
+diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp
+--- a/dom/console/Console.cpp
++++ b/dom/console/Console.cpp
+@@ -1,15 +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/Console.h"
++#include "mozilla/dom/ConsoleInstance.h"
+ #include "mozilla/dom/ConsoleBinding.h"
+ 
+ #include "mozilla/dom/BlobBinding.h"
+ #include "mozilla/dom/Exceptions.h"
+ #include "mozilla/dom/File.h"
+ #include "mozilla/dom/FunctionBinding.h"
+ #include "mozilla/dom/Performance.h"
+ #include "mozilla/dom/ScriptSettings.h"
+@@ -948,30 +949,32 @@ METHOD(Log, "log")
+ METHOD(Info, "info")
+ METHOD(Warn, "warn")
+ METHOD(Error, "error")
+ METHOD(Exception, "exception")
+ METHOD(Debug, "debug")
+ METHOD(Table, "table")
+ METHOD(Trace, "trace")
+ 
++// Displays an interactive listing of all the properties of an object.
++METHOD(Dir, "dir");
++METHOD(Dirxml, "dirxml");
++
++METHOD(Group, "group")
++METHOD(GroupCollapsed, "groupCollapsed")
++
++#undef METHOD
++
+ /* static */ void
+ Console::Clear(const GlobalObject& aGlobal)
+ {
+   const Sequence<JS::Value> data;
+   Method(aGlobal, MethodClear, NS_LITERAL_STRING("clear"), data);
+ }
+ 
+-// Displays an interactive listing of all the properties of an object.
+-METHOD(Dir, "dir");
+-METHOD(Dirxml, "dirxml");
+-
+-METHOD(Group, "group")
+-METHOD(GroupCollapsed, "groupCollapsed")
+-
+ /* static */ void
+ Console::GroupEnd(const GlobalObject& aGlobal)
+ {
+   const Sequence<JS::Value> data;
+   Method(aGlobal, MethodGroupEnd, NS_LITERAL_STRING("groupEnd"), data);
+ }
+ 
+ /* static */ void
+@@ -985,33 +988,45 @@ Console::TimeEnd(const GlobalObject& aGl
+ {
+   StringMethod(aGlobal, aLabel, MethodTimeEnd, NS_LITERAL_STRING("timeEnd"));
+ }
+ 
+ /* static */ void
+ Console::StringMethod(const GlobalObject& aGlobal, const nsAString& aLabel,
+                       MethodName aMethodName, const nsAString& aMethodString)
+ {
+-  JSContext* cx = aGlobal.Context();
+-
+-  ClearException ce(cx);
++  RefPtr<Console> console = GetConsole(aGlobal);
++  if (!console) {
++    return;
++  }
++
++  console->StringMethodInternal(aGlobal.Context(), aLabel, aMethodName,
++                                aMethodString);
++}
++
++void
++Console::StringMethodInternal(JSContext* aCx, const nsAString& aLabel,
++                              MethodName aMethodName,
++                              const nsAString& aMethodString)
++{
++  ClearException ce(aCx);
+ 
+   Sequence<JS::Value> data;
+-  SequenceRooter<JS::Value> rooter(cx, &data);
+-
+-  JS::Rooted<JS::Value> value(cx);
+-  if (!dom::ToJSValue(cx, aLabel, &value)) {
++  SequenceRooter<JS::Value> rooter(aCx, &data);
++
++  JS::Rooted<JS::Value> value(aCx);
++  if (!dom::ToJSValue(aCx, aLabel, &value)) {
+     return;
+   }
+ 
+   if (!data.AppendElement(value, fallible)) {
+     return;
+   }
+ 
+-  Method(aGlobal, aMethodName, aMethodString, data);
++  MethodInternal(aCx, aMethodName, aMethodString, data);
+ }
+ 
+ /* static */ void
+ Console::TimeStamp(const GlobalObject& aGlobal,
+                    const JS::Handle<JS::Value> aData)
+ {
+   JSContext* cx = aGlobal.Context();
+ 
+@@ -2506,16 +2521,24 @@ Console::MonotonicTimer(JSContext* aCx, 
+ 
+   WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
+   MOZ_ASSERT(workerPrivate);
+ 
+   *aTimeStamp = workerPrivate->TimeStampToDOMHighRes(TimeStamp::Now());
+   return true;
+ }
+ 
++/* static */ already_AddRefed<ConsoleInstance>
++Console::CreateInstance(const GlobalObject& aGlobal,
++                        const ConsoleInstanceOptions& aOptions)
++{
++  RefPtr<ConsoleInstance> console = new ConsoleInstance(aOptions);
++  return console.forget();
++}
++
+ //  Bug 1425574 part 4 adds this.
+ //  void
+ //  Console::MaybeExecuteDumpFunctionForTrace(JSContext* aCx, nsIStackFrame* aStack)
+ //  {
+ //    if (!aStack || (!mDumpFunction && !mDumpToStdout)) {
+ //      return;
+ //    }
+ //
+diff --git a/dom/console/Console.h b/dom/console/Console.h
+--- a/dom/console/Console.h
++++ b/dom/console/Console.h
+@@ -22,19 +22,21 @@
+ class nsIConsoleAPIStorage;
+ class nsIPrincipal;
+ 
+ namespace mozilla {
+ namespace dom {
+ 
+ class AnyCallback;
+ class ConsoleCallData;
++class ConsoleInstance;
+ class ConsoleRunnable;
+ class ConsoleCallDataRunnable;
+ class ConsoleProfileRunnable;
++struct ConsoleInstanceOptions;
+ struct ConsoleTimerError;
+ struct ConsoleStackEntry;
+ 
+ class Console final : public nsIObserver
+                     , public nsSupportsWeakReference
+ {
+ public:
+   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+@@ -109,16 +111,20 @@ public:
+          const Sequence<JS::Value>& aData);
+ 
+   static void
+   Count(const GlobalObject& aGlobal, const nsAString& aLabel);
+ 
+   static void
+   Clear(const GlobalObject& aGlobal);
+ 
++  static already_AddRefed<ConsoleInstance>
++  CreateInstance(const GlobalObject& aGlobal,
++                 const ConsoleInstanceOptions& aOptions);
++
+   void
+   ClearStorage();
+ 
+   void
+   RetrieveConsoleEvents(JSContext* aCx, nsTArray<JS::Value>& aEvents,
+                         ErrorResult& aRv);
+ 
+   void
+@@ -178,16 +184,20 @@ private:
+   void
+   MethodInternal(JSContext* aCx, MethodName aName,
+                  const nsAString& aString, const Sequence<JS::Value>& aData);
+ 
+   static void
+   StringMethod(const GlobalObject& aGlobal, const nsAString& aLabel,
+                MethodName aMethodName, const nsAString& aMethodString);
+ 
++  void
++  StringMethodInternal(JSContext* aCx, const nsAString& aLabel,
++                       MethodName aMethodName, const nsAString& aMethodString);
++
+   // This method must receive aCx and aArguments in the same JSCompartment.
+   void
+   ProcessCallData(JSContext* aCx,
+                   ConsoleCallData* aData,
+                   const Sequence<JS::Value>& aArguments);
+ 
+   void
+   StoreCallData(ConsoleCallData* aData);
+@@ -412,16 +422,17 @@ private:
+     eShuttingDown
+   } mStatus;
+ 
+   // This is used when Console is created and it's used only for JSM custom
+   // console instance.
+   mozilla::TimeStamp mCreationTimeStamp;
+ 
+   friend class ConsoleCallData;
++  friend class ConsoleInstance;
+   friend class ConsoleRunnable;
+   friend class ConsoleCallDataRunnable;
+   friend class ConsoleProfileRunnable;
+ };
+ 
+ } // namespace dom
+ } // namespace mozilla
+ 
+diff --git a/dom/console/ConsoleInstance.cpp b/dom/console/ConsoleInstance.cpp
+new file mode 100644
+--- /dev/null
++++ b/dom/console/ConsoleInstance.cpp
+@@ -0,0 +1,134 @@
++/* -*- 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/ConsoleInstance.h"
++#include "mozilla/dom/ConsoleBinding.h"
++
++namespace mozilla {
++namespace dom {
++
++NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ConsoleInstance, mConsole)
++
++NS_IMPL_CYCLE_COLLECTING_ADDREF(ConsoleInstance)
++NS_IMPL_CYCLE_COLLECTING_RELEASE(ConsoleInstance)
++
++NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ConsoleInstance)
++  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
++NS_INTERFACE_MAP_END
++
++ConsoleInstance::ConsoleInstance(const ConsoleInstanceOptions& aOptions)
++  : mConsole(new Console(nullptr))
++{}
++
++ConsoleInstance::~ConsoleInstance()
++{}
++
++JSObject*
++ConsoleInstance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
++{
++  return ConsoleInstanceBinding::Wrap(aCx, this, aGivenProto);
++}
++
++#define METHOD(name, string)                                               \
++  void                                                                     \
++  ConsoleInstance::name(JSContext* aCx, const Sequence<JS::Value>& aData)  \
++  {                                                                        \
++    mConsole->MethodInternal(aCx, Console::Method##name,                   \
++                             NS_LITERAL_STRING(string), aData);            \
++  }
++
++METHOD(Log, "log")
++METHOD(Info, "info")
++METHOD(Warn, "warn")
++METHOD(Error, "error")
++METHOD(Exception, "exception")
++METHOD(Debug, "debug")
++METHOD(Table, "table")
++METHOD(Trace, "trace")
++METHOD(Dir, "dir");
++METHOD(Dirxml, "dirxml");
++METHOD(Group, "group")
++METHOD(GroupCollapsed, "groupCollapsed")
++
++#undef METHOD
++
++void
++ConsoleInstance::GroupEnd(JSContext* aCx)
++{
++  const Sequence<JS::Value> data;
++  mConsole->MethodInternal(aCx, Console::MethodGroupEnd,
++                           NS_LITERAL_STRING("groupEnd"), data);
++}
++
++void
++ConsoleInstance::Time(JSContext* aCx, const nsAString& aLabel)
++{
++  mConsole->StringMethodInternal(aCx, aLabel, Console::MethodTime,
++                                 NS_LITERAL_STRING("time"));
++}
++
++void
++ConsoleInstance::TimeEnd(JSContext* aCx, const nsAString& aLabel)
++{
++  mConsole->StringMethodInternal(aCx, aLabel, Console::MethodTimeEnd,
++                                 NS_LITERAL_STRING("timeEnd"));
++}
++
++void
++ConsoleInstance::TimeStamp(JSContext* aCx, const JS::Handle<JS::Value> aData)
++{
++  ClearException ce(aCx);
++
++  Sequence<JS::Value> data;
++  SequenceRooter<JS::Value> rooter(aCx, &data);
++
++  if (aData.isString() && !data.AppendElement(aData, fallible)) {
++    return;
++  }
++
++  mConsole->MethodInternal(aCx, Console::MethodTimeStamp,
++                           NS_LITERAL_STRING("timeStamp"), data);
++}
++
++void
++ConsoleInstance::Profile(JSContext* aCx, const Sequence<JS::Value>& aData)
++{
++  mConsole->ProfileMethodInternal(aCx, NS_LITERAL_STRING("profile"), aData);
++}
++
++void
++ConsoleInstance::ProfileEnd(JSContext* aCx, const Sequence<JS::Value>& aData)
++{
++  mConsole->ProfileMethodInternal(aCx, NS_LITERAL_STRING("profileEnd"), aData);
++}
++
++void
++ConsoleInstance::Assert(JSContext* aCx, bool aCondition,
++                        const Sequence<JS::Value>& aData)
++{
++  if (!aCondition) {
++    mConsole->MethodInternal(aCx, Console::MethodAssert,
++                             NS_LITERAL_STRING("assert"), aData);
++  }
++}
++
++void
++ConsoleInstance::Count(JSContext* aCx, const nsAString& aLabel)
++{
++  mConsole->StringMethodInternal(aCx, aLabel, Console::MethodCount,
++                                 NS_LITERAL_STRING("count"));
++}
++
++void
++ConsoleInstance::Clear(JSContext* aCx)
++{
++  const Sequence<JS::Value> data;
++  mConsole->MethodInternal(aCx, Console::MethodClear,
++                           NS_LITERAL_STRING("clear"), data);
++}
++
++} // namespace dom
++} // namespace mozilla
+diff --git a/dom/console/ConsoleInstance.h b/dom/console/ConsoleInstance.h
+new file mode 100644
+--- /dev/null
++++ b/dom/console/ConsoleInstance.h
+@@ -0,0 +1,106 @@
++/* -*- 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/. */
++
++#ifndef mozilla_dom_ConsoleInstance_h
++#define mozilla_dom_ConsoleInstance_h
++
++#include "mozilla/dom/Console.h"
++
++
++namespace mozilla {
++namespace dom {
++
++class ConsoleInstance final : public nsISupports
++                            , public nsWrapperCache
++{
++public:
++  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
++  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ConsoleInstance)
++
++  explicit ConsoleInstance(const ConsoleInstanceOptions& aOptions);
++
++  // WebIDL methods
++  JSObject*
++  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
++
++  nsPIDOMWindowInner* GetParentObject() const
++  {
++    return nullptr;
++  }
++
++  void
++  Log(JSContext* aCx, const Sequence<JS::Value>& aData);
++
++  void
++  Info(JSContext* aCx, const Sequence<JS::Value>& aData);
++
++  void
++  Warn(JSContext* aCx, const Sequence<JS::Value>& aData);
++
++  void
++  Error(JSContext* aCx, const Sequence<JS::Value>& aData);
++
++  void
++  Exception(JSContext* aCx, const Sequence<JS::Value>& aData);
++
++  void
++  Debug(JSContext* aCx, const Sequence<JS::Value>& aData);
++
++  void
++  Table(JSContext* aCx, const Sequence<JS::Value>& aData);
++
++  void
++  Trace(JSContext* aCx, const Sequence<JS::Value>& aData);
++
++  void
++  Dir(JSContext* aCx, const Sequence<JS::Value>& aData);
++
++  void
++  Dirxml(JSContext* aCx, const Sequence<JS::Value>& aData);
++
++  void
++  Group(JSContext* aCx, const Sequence<JS::Value>& aData);
++
++  void
++  GroupCollapsed(JSContext* aCx, const Sequence<JS::Value>& aData);
++
++  void
++  GroupEnd(JSContext* aCx);
++
++  void
++  Time(JSContext* aCx, const nsAString& aLabel);
++
++  void
++  TimeEnd(JSContext* aCx, const nsAString& aLabel);
++
++  void
++  TimeStamp(JSContext* aCx, const JS::Handle<JS::Value> aData);
++
++  void
++  Profile(JSContext* aCx, const Sequence<JS::Value>& aData);
++
++  void
++  ProfileEnd(JSContext* aCx, const Sequence<JS::Value>& aData);
++
++  void
++  Assert(JSContext* aCx, bool aCondition, const Sequence<JS::Value>& aData);
++
++  void
++  Count(JSContext* aCx, const nsAString& aLabel);
++
++  void
++  Clear(JSContext* aCx);
++
++private:
++  ~ConsoleInstance();
++
++  RefPtr<Console> mConsole;
++};
++
++} // dom namespace
++} // mozilla namespace
++
++#endif // mozilla_dom_ConsoleInstance_h
+diff --git a/dom/console/moz.build b/dom/console/moz.build
+--- a/dom/console/moz.build
++++ b/dom/console/moz.build
+@@ -18,20 +18,22 @@ EXPORTS += [
+ ]
+ 
+ EXPORTS.mozilla += [
+     'ConsoleReportCollector.h',
+ ]
+ 
+ EXPORTS.mozilla.dom += [
+     'Console.h',
++    'ConsoleInstance.h',
+ ]
+ 
+ UNIFIED_SOURCES += [
+     'Console.cpp',
++    'ConsoleInstance.cpp',
+     'ConsoleReportCollector.cpp',
+ ]
+ 
+ EXTRA_COMPONENTS += [
+     'ConsoleAPI.manifest',
+     'ConsoleAPIStorage.js',
+ ]
+ 
+diff --git a/dom/console/tests/console.jsm b/dom/console/tests/console.jsm
+--- a/dom/console/tests/console.jsm
++++ b/dom/console/tests/console.jsm
+@@ -2,10 +2,11 @@
+  * Any copyright is dedicated to the Public Domain.
+  * http://creativecommons.org/publicdomain/zero/1.0/
+  */
+ this.EXPORTED_SYMBOLS = [ "ConsoleTest" ];
+ 
+ this.ConsoleTest = {
+   go: function() {
+     console.log("Hello world!");
++    console.createInstance().log("Hello world!");
+   }
+ };
+diff --git a/dom/console/tests/test_jsm.xul b/dom/console/tests/test_jsm.xul
+--- a/dom/console/tests/test_jsm.xul
++++ b/dom/console/tests/test_jsm.xul
+@@ -17,25 +17,31 @@
+ 
+ const JSM = "chrome://mochitests/content/chrome/dom/console/tests/console.jsm";
+ 
+ function consoleListener() {
+   SpecialPowers.addObserver(this, "console-api-log-event");
+ }
+ 
+ consoleListener.prototype  = {
++  count: 0,
++
+   observe: function(aSubject, aTopic, aData) {
+     if (aTopic == "console-api-log-event") {
+       var obj = aSubject.wrappedJSObject;
+       if (obj.innerID == JSM) {
+         is(obj.ID, "jsm", "ID and InnerID are correctly set.");
+         is (obj.arguments[0], "Hello world!", "Message matches");
+ 
+-        SpecialPowers.removeObserver(this, "console-api-log-event");
+-        SimpleTest.finish();
++        // We want to see 2 messages, the first is generated by console.log,
++        // the second one from createInstance().log();
++        if (++this.count == 2) {
++          SpecialPowers.removeObserver(this, "console-api-log-event");
++          SimpleTest.finish();
++        }
+       }
+     }
+   }
+ }
+ function test() {
+   SimpleTest.waitForExplicitFinish();
+ 
+   var cl = new consoleListener();
+diff --git a/dom/webidl/Console.webidl b/dom/webidl/Console.webidl
+--- a/dom/webidl/Console.webidl
++++ b/dom/webidl/Console.webidl
+@@ -7,16 +7,20 @@
+  * For more information on this interface, please see
+  * https://console.spec.whatwg.org/#console-namespace
+  */
+ 
+ [Exposed=(Window,Worker,WorkerDebugger,Worklet,System),
+  ClassString="Console",
+  ProtoObjectHack]
+ namespace console {
++
++  // NOTE: if you touch this namespace, remember to update the ConsoleInstance
++  // interface as well!
++
+   // Logging
+   void assert(optional boolean condition = false, any... data);
+   void clear();
+   void count(optional DOMString label = "default");
+   void debug(any... data);
+   void error(any... data);
+   void info(any... data);
+   void log(any... data);
+@@ -40,16 +44,19 @@ namespace console {
+   void _exception(any... data);
+   void timeStamp(optional any data);
+ 
+   void profile(any... data);
+   void profileEnd(any... data);
+ 
+   [ChromeOnly]
+   const boolean IS_NATIVE_CONSOLE = true;
++
++  [ChromeOnly, NewObject]
++  ConsoleInstance createInstance(optional ConsoleInstanceOptions options);
+ };
+ 
+ // This is used to propagate console events to the observers.
+ dictionary ConsoleEvent {
+   (unsigned long long or DOMString) ID;
+   (unsigned long long or DOMString) innerID;
+   DOMString addonId = "";
+   DOMString level = "";
+@@ -104,8 +111,48 @@ dictionary ConsoleTimerError {
+ dictionary ConsoleCounter {
+   DOMString label = "";
+   unsigned long count = 0;
+ };
+ 
+ dictionary ConsoleCounterError {
+   DOMString error = "maxCountersExceeded";
+ };
++
++[ChromeOnly,
++ Exposed=(Window,Worker,WorkerDebugger,Worklet,System)]
++// This is basically a copy of the console namespace.
++interface ConsoleInstance {
++  // Logging
++  void assert(optional boolean condition = false, any... data);
++  void clear();
++  void count(optional DOMString label = "default");
++  void debug(any... data);
++  void error(any... data);
++  void info(any... data);
++  void log(any... data);
++  void table(any... data); // FIXME: The spec is still unclear about this.
++  void trace(any... data);
++  void warn(any... data);
++  void dir(any... data); // FIXME: This doesn't follow the spec yet.
++  void dirxml(any... data);
++
++  // Grouping
++  void group(any... data);
++  void groupCollapsed(any... data);
++  void groupEnd();
++
++  // Timing
++  void time(optional DOMString label = "default");
++  void timeEnd(optional DOMString label = "default");
++
++  // Mozilla only or Webcompat methods
++
++  void _exception(any... data);
++  void timeStamp(optional any data);
++
++  void profile(any... data);
++  void profileEnd(any... data);
++};
++
++dictionary ConsoleInstanceOptions {
++  // TODO
++};

+ 156 - 0
mozilla-release/patches/1425574-2-59a1.patch

@@ -0,0 +1,156 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1515089983 -3600
+# Node ID bb19ee84ce26ee97dc599704ec8ba178bab1e9f5
+# Parent  49b981835673d69deff8e03235af2ebe5237d1ec
+Bug 1425574 - Fill the feature gap between Console.jsm and Console API - part 2 - consoleID in ConsoleEvent, r=smaug, r=bgrins
+
+diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp
+--- a/dom/console/Console.cpp
++++ b/dom/console/Console.cpp
+@@ -1476,16 +1476,17 @@ Console::PopulateConsoleNotificationInTh
+     event.mInnerID.Value().SetAsUnsignedLongLong() = aData->mInnerIDNumber;
+   } else {
+     // aData->mIDType can be eUnknown when we dispatch notifications via
+     // mConsoleEventNotifier.
+     event.mID.Value().SetAsUnsignedLongLong() = 0;
+     event.mInnerID.Value().SetAsUnsignedLongLong() = 0;
+   }
+ 
++  event.mConsoleID = mConsoleID;
+   event.mLevel = aData->mMethodString;
+   event.mFilename = frame.mFilename;
+ 
+   nsCOMPtr<nsIURI> filenameURI;
+   nsAutoCString pass;
+   if (NS_IsMainThread() &&
+       NS_SUCCEEDED(NS_NewURI(getter_AddRefs(filenameURI), frame.mFilename)) &&
+       NS_SUCCEEDED(filenameURI->GetPassword(pass)) && !pass.IsEmpty()) {
+diff --git a/dom/console/Console.h b/dom/console/Console.h
+--- a/dom/console/Console.h
++++ b/dom/console/Console.h
+@@ -410,16 +410,17 @@ private:
+ 
+   RefPtr<AnyCallback> mConsoleEventNotifier;
+ 
+   // This is the stack for groupping.
+   nsTArray<nsString> mGroupStack;
+ 
+   uint64_t mOuterID;
+   uint64_t mInnerID;
++  nsString mConsoleID;
+ 
+   enum {
+     eUnknown,
+     eInitialized,
+     eShuttingDown
+   } mStatus;
+ 
+   // This is used when Console is created and it's used only for JSM custom
+diff --git a/dom/console/ConsoleInstance.cpp b/dom/console/ConsoleInstance.cpp
+--- a/dom/console/ConsoleInstance.cpp
++++ b/dom/console/ConsoleInstance.cpp
+@@ -16,17 +16,19 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(ConsoleI
+ NS_IMPL_CYCLE_COLLECTING_RELEASE(ConsoleInstance)
+ 
+ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ConsoleInstance)
+   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_END
+ 
+ ConsoleInstance::ConsoleInstance(const ConsoleInstanceOptions& aOptions)
+   : mConsole(new Console(nullptr))
+-{}
++{
++  mConsole->mConsoleID = aOptions.mConsoleID;
++}
+ 
+ ConsoleInstance::~ConsoleInstance()
+ {}
+ 
+ JSObject*
+ ConsoleInstance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+ {
+   return ConsoleInstanceBinding::Wrap(aCx, this, aGivenProto);
+diff --git a/dom/console/tests/console.jsm b/dom/console/tests/console.jsm
+--- a/dom/console/tests/console.jsm
++++ b/dom/console/tests/console.jsm
+@@ -2,11 +2,13 @@
+  * Any copyright is dedicated to the Public Domain.
+  * http://creativecommons.org/publicdomain/zero/1.0/
+  */
+ this.EXPORTED_SYMBOLS = [ "ConsoleTest" ];
+ 
+ this.ConsoleTest = {
+   go: function() {
+     console.log("Hello world!");
+-    console.createInstance().log("Hello world!");
++    console.createInstance({
++      consoleID: "wow",
++    }).log("Hello world!");
+   }
+ };
+diff --git a/dom/console/tests/test_jsm.xul b/dom/console/tests/test_jsm.xul
+--- a/dom/console/tests/test_jsm.xul
++++ b/dom/console/tests/test_jsm.xul
+@@ -26,16 +26,22 @@ consoleListener.prototype  = {
+ 
+   observe: function(aSubject, aTopic, aData) {
+     if (aTopic == "console-api-log-event") {
+       var obj = aSubject.wrappedJSObject;
+       if (obj.innerID == JSM) {
+         is(obj.ID, "jsm", "ID and InnerID are correctly set.");
+         is (obj.arguments[0], "Hello world!", "Message matches");
+ 
++        if (this.count == 0) {
++          is(obj.consoleID, "", "No consoleID for console API");
++        } else {
++          is(obj.consoleID, "wow", "consoleID is set by consoleInstance");
++        }
++
+         // We want to see 2 messages, the first is generated by console.log,
+         // the second one from createInstance().log();
+         if (++this.count == 2) {
+           SpecialPowers.removeObserver(this, "console-api-log-event");
+           SimpleTest.finish();
+         }
+       }
+     }
+diff --git a/dom/webidl/Console.webidl b/dom/webidl/Console.webidl
+--- a/dom/webidl/Console.webidl
++++ b/dom/webidl/Console.webidl
+@@ -53,16 +53,17 @@ namespace console {
+   [ChromeOnly, NewObject]
+   ConsoleInstance createInstance(optional ConsoleInstanceOptions options);
+ };
+ 
+ // This is used to propagate console events to the observers.
+ dictionary ConsoleEvent {
+   (unsigned long long or DOMString) ID;
+   (unsigned long long or DOMString) innerID;
++  DOMString consoleID = "";
+   DOMString addonId = "";
+   DOMString level = "";
+   DOMString filename = "";
+   unsigned long lineNumber = 0;
+   unsigned long columnNumber = 0;
+   DOMString functionName = "";
+   double timeStamp = 0;
+   sequence<any> arguments;
+@@ -149,10 +150,16 @@ interface ConsoleInstance {
+   void _exception(any... data);
+   void timeStamp(optional any data);
+ 
+   void profile(any... data);
+   void profileEnd(any... data);
+ };
+ 
+ dictionary ConsoleInstanceOptions {
+-  // TODO
++/* TODO:
++  boolean dump = false;
++  DOMString prefix = "";
++  DOMString maxLogLevel = "";
++  DOMString innerID = "";
++*/
++  DOMString consoleID = "";
+ };

+ 157 - 0
mozilla-release/patches/1425574-3-59a1.patch

@@ -0,0 +1,157 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1515089983 -3600
+# Node ID 1bd2d2b4d9e628a9d4c7376787da289e2f50abb9
+# Parent  3e30d8ac7f857952fd69852ab5cd6c7c308f07ee
+Bug 1425574 - Fill the feature gap between Console.jsm and Console API - part 3 - custom innerID, r=smaug
+
+diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp
+--- a/dom/console/Console.cpp
++++ b/dom/console/Console.cpp
+@@ -1312,16 +1312,18 @@ Console::MethodInternal(JSContext* aCx, 
+     if (!callData->mCountValue) {
+       return;
+     }
+   }
+ 
+   if (NS_IsMainThread()) {
+     if (mWindow) {
+       callData->SetIDs(mOuterID, mInnerID);
++    } else if (!mPassedInnerID.IsEmpty()) {
++      callData->SetIDs(NS_LITERAL_STRING("jsm"), mPassedInnerID);
+     } else {
+       nsAutoString filename;
+       if (callData->mTopStackFrame.isSome()) {
+         filename = callData->mTopStackFrame->mFilename;
+       }
+ 
+       callData->SetIDs(NS_LITERAL_STRING("jsm"), filename);
+     }
+diff --git a/dom/console/Console.h b/dom/console/Console.h
+--- a/dom/console/Console.h
++++ b/dom/console/Console.h
+@@ -410,17 +410,20 @@ private:
+ 
+   RefPtr<AnyCallback> mConsoleEventNotifier;
+ 
+   // This is the stack for groupping.
+   nsTArray<nsString> mGroupStack;
+ 
+   uint64_t mOuterID;
+   uint64_t mInnerID;
++
++  // Set only by ConsoleInstance:
+   nsString mConsoleID;
++  nsString mPassedInnerID;
+ 
+   enum {
+     eUnknown,
+     eInitialized,
+     eShuttingDown
+   } mStatus;
+ 
+   // This is used when Console is created and it's used only for JSM custom
+diff --git a/dom/console/ConsoleInstance.cpp b/dom/console/ConsoleInstance.cpp
+--- a/dom/console/ConsoleInstance.cpp
++++ b/dom/console/ConsoleInstance.cpp
+@@ -18,16 +18,17 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(Console
+ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ConsoleInstance)
+   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_END
+ 
+ ConsoleInstance::ConsoleInstance(const ConsoleInstanceOptions& aOptions)
+   : mConsole(new Console(nullptr))
+ {
+   mConsole->mConsoleID = aOptions.mConsoleID;
++  mConsole->mPassedInnerID = aOptions.mInnerID;
+ }
+ 
+ ConsoleInstance::~ConsoleInstance()
+ {}
+ 
+ JSObject*
+ ConsoleInstance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+ {
+diff --git a/dom/console/tests/console.jsm b/dom/console/tests/console.jsm
+--- a/dom/console/tests/console.jsm
++++ b/dom/console/tests/console.jsm
+@@ -2,13 +2,15 @@
+  * Any copyright is dedicated to the Public Domain.
+  * http://creativecommons.org/publicdomain/zero/1.0/
+  */
+ this.EXPORTED_SYMBOLS = [ "ConsoleTest" ];
+ 
+ this.ConsoleTest = {
+   go: function() {
+     console.log("Hello world!");
++    console.createInstance().log("Hello world!");
+     console.createInstance({
+       consoleID: "wow",
++      innerID: "CUSTOM INNER",
+     }).log("Hello world!");
+   }
+ };
+diff --git a/dom/console/tests/test_jsm.xul b/dom/console/tests/test_jsm.xul
+--- a/dom/console/tests/test_jsm.xul
++++ b/dom/console/tests/test_jsm.xul
+@@ -25,29 +25,31 @@ consoleListener.prototype  = {
+   count: 0,
+ 
+   observe: function(aSubject, aTopic, aData) {
+     if (aTopic == "console-api-log-event") {
+       var obj = aSubject.wrappedJSObject;
+       if (obj.innerID == JSM) {
+         is(obj.ID, "jsm", "ID and InnerID are correctly set.");
+         is (obj.arguments[0], "Hello world!", "Message matches");
+-
+-        if (this.count == 0) {
+-          is(obj.consoleID, "", "No consoleID for console API");
+-        } else {
+-          is(obj.consoleID, "wow", "consoleID is set by consoleInstance");
+-        }
++        is(obj.consoleID, "", "No consoleID for console API");
+ 
+-        // We want to see 2 messages, the first is generated by console.log,
+-        // the second one from createInstance().log();
+-        if (++this.count == 2) {
+-          SpecialPowers.removeObserver(this, "console-api-log-event");
+-          SimpleTest.finish();
+-        }
++        // We want to see 2 messages from this innerID, the first is generated
++        // by console.log, the second one from createInstance().log();
++        ++this.count;
++      } else if (obj.innerID = "CUSTOM INNER") {
++        is(obj.ID, "jsm", "ID and InnerID are correctly set.");
++        is (obj.arguments[0], "Hello world!", "Message matches");
++        is(obj.consoleID, "wow", "consoleID is set by consoleInstance");
++        ++this.count;
++      }
++
++      if (this.count == 3) {
++        SpecialPowers.removeObserver(this, "console-api-log-event");
++        SimpleTest.finish();
+       }
+     }
+   }
+ }
+ function test() {
+   SimpleTest.waitForExplicitFinish();
+ 
+   var cl = new consoleListener();
+diff --git a/dom/webidl/Console.webidl b/dom/webidl/Console.webidl
+--- a/dom/webidl/Console.webidl
++++ b/dom/webidl/Console.webidl
+@@ -154,12 +154,12 @@ interface ConsoleInstance {
+   void profileEnd(any... data);
+ };
+ 
+ dictionary ConsoleInstanceOptions {
+ /* TODO:
+   boolean dump = false;
+   DOMString prefix = "";
+   DOMString maxLogLevel = "";
++*/
+   DOMString innerID = "";
+-*/
+   DOMString consoleID = "";
+ };

+ 500 - 0
mozilla-release/patches/1425574-4-59a1.patch

@@ -0,0 +1,500 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1515089984 -3600
+# Node ID 465b929da94d51a1224dd0972432d6a2cf783b30
+# Parent  088612381a359035f50639e4fdccbaab26efb967
+Bug 1425574 - Fill the feature gap between Console.jsm and Console API - part 4 - dump function, r=smaug, r=bgrins
+
+diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp
+--- a/dom/console/Console.cpp
++++ b/dom/console/Console.cpp
+@@ -768,22 +768,24 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(Console)
+ 
+ // We don't need to traverse/unlink mStorage and mSandbox because they are not
+ // CCed objects and they are only used on the main thread, even when this
+ // Console object is used on workers.
+ 
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Console)
+   NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
+   NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsoleEventNotifier)
++  NS_IMPL_CYCLE_COLLECTION_UNLINK(mDumpFunction)
+   tmp->Shutdown();
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+ 
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Console)
+   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
+   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsoleEventNotifier)
++  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDumpFunction)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+ 
+ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Console)
+   for (uint32_t i = 0; i < tmp->mCallDataStorage.Length(); ++i) {
+     tmp->mCallDataStorage[i]->Trace(aCallbacks, aClosure);
+   }
+ 
+   for (uint32_t i = 0; i < tmp->mCallDataStoragePending.Length(); ++i) {
+@@ -814,16 +816,17 @@ Console::Create(nsPIDOMWindowInner* aWin
+ 
+   return console.forget();
+ }
+ 
+ Console::Console(nsPIDOMWindowInner* aWindow)
+   : mWindow(aWindow)
+   , mOuterID(0)
+   , mInnerID(0)
++  , mDumpToStdout(false)
+   , mStatus(eUnknown)
+   , mCreationTimeStamp(TimeStamp::Now())
+ {
+   if (mWindow) {
+     MOZ_ASSERT(mWindow->IsInnerWindow());
+     mInnerID = mWindow->WindowID();
+ 
+     // Without outerwindow any console message coming from this object will not
+@@ -1072,16 +1075,18 @@ void
+ Console::ProfileMethodInternal(JSContext* aCx, const nsAString& aAction,
+                                const Sequence<JS::Value>& aData)
+ {
+   // Make all Console API no-op if DevTools aren't enabled.
+   if (!nsContentUtils::DevToolsEnabled(aCx)) {
+     return;
+   }
+ 
++  MaybeExecuteDumpFunction(aCx, aAction, aData);
++
+   if (!NS_IsMainThread()) {
+     // Here we are in a worker thread.
+     RefPtr<ConsoleProfileRunnable> runnable =
+       new ConsoleProfileRunnable(this, aAction, aData);
+ 
+     runnable->Dispatch(aCx);
+     return;
+   }
+@@ -1206,16 +1211,17 @@ void
+ Console::MethodInternal(JSContext* aCx, MethodName aMethodName,
+                         const nsAString& aMethodString,
+                         const Sequence<JS::Value>& aData)
+ {
+   // Make all Console API no-op if DevTools aren't enabled.
+   if (!nsContentUtils::DevToolsEnabled(aCx)) {
+     return;
+   }
++
+   AssertIsOnOwningThread();
+ 
+   RefPtr<ConsoleCallData> callData(new ConsoleCallData());
+ 
+   ClearException ce(aCx);
+ 
+   if (NS_WARN_IF(!callData->Initialize(aCx, aMethodName, aMethodString,
+                                        aData, this))) {
+@@ -1309,16 +1315,24 @@ Console::MethodInternal(JSContext* aCx, 
+ 
+   else if (aMethodName == MethodCount) {
+     callData->mCountValue = IncreaseCounter(aCx, aData, callData->mCountLabel);
+     if (!callData->mCountValue) {
+       return;
+     }
+   }
+ 
++  // Before processing this CallData differently, it's time to call the dump
++  // function.
++  if (aMethodName == MethodTrace) {
++    MaybeExecuteDumpFunctionForTrace(aCx, stack);
++  } else {
++    MaybeExecuteDumpFunction(aCx, aMethodString, aData);
++  }
++
+   if (NS_IsMainThread()) {
+     if (mWindow) {
+       callData->SetIDs(mOuterID, mInnerID);
+     } else if (!mPassedInnerID.IsEmpty()) {
+       callData->SetIDs(NS_LITERAL_STRING("jsm"), mPassedInnerID);
+     } else {
+       nsAutoString filename;
+       if (callData->mTopStackFrame.isSome()) {
+@@ -2532,66 +2546,106 @@ Console::MonotonicTimer(JSContext* aCx, 
+ /* static */ already_AddRefed<ConsoleInstance>
+ Console::CreateInstance(const GlobalObject& aGlobal,
+                         const ConsoleInstanceOptions& aOptions)
+ {
+   RefPtr<ConsoleInstance> console = new ConsoleInstance(aOptions);
+   return console.forget();
+ }
+ 
+-//  Bug 1425574 part 4 adds this.
+-//  void
+-//  Console::MaybeExecuteDumpFunctionForTrace(JSContext* aCx, nsIStackFrame* aStack)
+-//  {
+-//    if (!aStack || (!mDumpFunction && !mDumpToStdout)) {
+-//      return;
+-//    }
+-//
+-//    nsAutoString message;
+-//    message.AssignLiteral("console.trace:\n");
+-//
+-//    nsCOMPtr<nsIStackFrame> stack(aStack);
+-//  
+-//    while (stack) {
+-//      nsAutoString filename;
+-// -    nsresult rv = stack->GetFilename(aCx, filename);
+-// -    NS_ENSURE_SUCCESS_VOID(rv);
+-// +    stack->GetFilename(aCx, filename);
+-//
+-//      message.Append(filename);
+-//      message.AppendLiteral(" ");
+-//  
+-// -    int32_t lineNumber;
+-// -    nsresult rv = stack->GetLineNumber(aCx, &lineNumber);
+-// -    NS_ENSURE_SUCCESS_VOID(rv);
+-// -
+-// -    message.AppendInt(lineNumber);
+-// +    message.AppendInt(stack->GetLineNumber(aCx));
+-//      message.AppendLiteral(" ");
+-//
+-//      nsAutoString functionName;
+-// -    nsresult rv = stack->GetName(aCx, functionName);
+-// -    NS_ENSURE_SUCCESS_VOID(rv);
+-// +    stack->GetName(aCx, functionName);
+-//  
+-//      message.Append(filename);
+-//      message.AppendLiteral("\n");
+-//  
+-// -    nsCOMPtr<nsIStackFrame> caller;
+-// -    nsresult rv = stack->GetCaller(aCx, getter_AddRefs(caller));
+-// -    NS_ENSURE_SUCCESS_VOID(rv);
+-// +    nsCOMPtr<nsIStackFrame> caller = stack->GetCaller(aCx);
+-//  
+-//      if (!caller) {
+-// -      rv = stack->GetAsyncCaller(aCx, getter_AddRefs(caller));
+-// -      NS_ENSURE_SUCCESS_VOID(rv);
+-// +      caller = stack->GetAsyncCaller(aCx);
+-//      }
+-//
+-//      stack.swap(caller);
+-//    }
+-//  
+-//    message.AppendLiteral("\n");
+-//    ExecuteDumpFunction(message);
+-//  }
++void
++Console::MaybeExecuteDumpFunction(JSContext* aCx,
++                                  const nsAString& aMethodName,
++                                  const Sequence<JS::Value>& aData)
++{
++  if (!mDumpFunction && !mDumpToStdout) {
++    return;
++  }
++
++  nsAutoString message;
++  message.AssignLiteral("console.");
++  message.Append(aMethodName);
++  message.AppendLiteral(": ");
++
++  for (uint32_t i = 0; i < aData.Length(); ++i) {
++    JS::Rooted<JS::Value> v(aCx, aData[i]);
++    JS::Rooted<JSString*> jsString(aCx, JS_ValueToSource(aCx, v));
++    if (!jsString) {
++      continue;
++    }
++
++    nsAutoJSString string;
++    if (NS_WARN_IF(!string.init(aCx, jsString))) {
++      return;
++    }
++
++    if (i != 0) {
++      message.AppendLiteral(" ");
++    }
++
++    message.Append(string);
++  }
++
++  message.AppendLiteral("\n");
++  ExecuteDumpFunction(message);
++}
++
++void
++Console::MaybeExecuteDumpFunctionForTrace(JSContext* aCx, nsIStackFrame* aStack)
++{
++  if (!aStack || (!mDumpFunction && !mDumpToStdout)) {
++    return;
++  }
++
++  nsAutoString message;
++  message.AssignLiteral("console.trace:\n");
++
++  nsCOMPtr<nsIStackFrame> stack(aStack);
++
++  while (stack) {
++    nsAutoString filename;
++    stack->GetFilename(aCx, filename);
++
++    message.Append(filename);
++    message.AppendLiteral(" ");
++
++    message.AppendInt(stack->GetLineNumber(aCx));
++    message.AppendLiteral(" ");
++
++    nsAutoString functionName;
++    stack->GetName(aCx, functionName);
++
++    message.Append(filename);
++    message.AppendLiteral("\n");
++
++    nsCOMPtr<nsIStackFrame> caller = stack->GetCaller(aCx);
++
++    if (!caller) {
++      caller = stack->GetAsyncCaller(aCx);
++    }
++
++    stack.swap(caller);
++  }
++
++  message.AppendLiteral("\n");
++  ExecuteDumpFunction(message);
++}
++
++void
++Console::ExecuteDumpFunction(const nsAString& aMessage)
++{
++  if (mDumpFunction) {
++    IgnoredErrorResult rv;
++    mDumpFunction->Call(aMessage, rv);
++    return;
++  }
++
++  NS_ConvertUTF16toUTF8 str(aMessage);
++  MOZ_LOG(nsContentUtils::DOMDumpLog(), LogLevel::Debug, ("%s", str.get()));
++#ifdef ANDROID
++  __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", str.get());
++#endif
++  fputs(str.get(), stdout);
++  fflush(stdout);
++}
+ 
+ } // namespace dom
+ } // namespace mozilla
+diff --git a/dom/console/Console.h b/dom/console/Console.h
+--- a/dom/console/Console.h
++++ b/dom/console/Console.h
+@@ -16,23 +16,25 @@
+ #include "nsHashKeys.h"
+ #include "nsIObserver.h"
+ #include "nsWeakReference.h"
+ #include "nsDOMNavigationTiming.h"
+ #include "nsPIDOMWindow.h"
+ 
+ class nsIConsoleAPIStorage;
+ class nsIPrincipal;
++class nsIStackFrame;
+ 
+ namespace mozilla {
+ namespace dom {
+ 
+ class AnyCallback;
+ class ConsoleCallData;
+ class ConsoleInstance;
++class ConsoleInstanceDumpCallback;
+ class ConsoleRunnable;
+ class ConsoleCallDataRunnable;
+ class ConsoleProfileRunnable;
+ struct ConsoleInstanceOptions;
+ struct ConsoleTimerError;
+ struct ConsoleStackEntry;
+ 
+ class Console final : public nsIObserver
+@@ -381,16 +383,26 @@ private:
+   bool
+   IsShuttingDown() const;
+ 
+   bool
+   MonotonicTimer(JSContext* aCx, MethodName aMethodName,
+                  const Sequence<JS::Value>& aData,
+                  DOMHighResTimeStamp* aTimeStamp);
+ 
++  void
++  MaybeExecuteDumpFunction(JSContext* aCx, const nsAString& aMethodName,
++                           const Sequence<JS::Value>& aData);
++
++  void
++  MaybeExecuteDumpFunctionForTrace(JSContext* aCx, nsIStackFrame* aStack);
++
++  void
++  ExecuteDumpFunction(const nsAString& aMessage);
++
+   // All these nsCOMPtr are touched on main thread only.
+   nsCOMPtr<nsPIDOMWindowInner> mWindow;
+   nsCOMPtr<nsIConsoleAPIStorage> mStorage;
+   RefPtr<JSObjectHolder> mSandbox;
+ 
+   // Touched on the owner thread.
+   nsDataHashtable<nsStringHashKey, DOMHighResTimeStamp> mTimerRegistry;
+   nsDataHashtable<nsStringHashKey, uint32_t> mCounterRegistry;
+@@ -414,16 +426,18 @@ private:
+   nsTArray<nsString> mGroupStack;
+ 
+   uint64_t mOuterID;
+   uint64_t mInnerID;
+ 
+   // Set only by ConsoleInstance:
+   nsString mConsoleID;
+   nsString mPassedInnerID;
++  RefPtr<ConsoleInstanceDumpCallback> mDumpFunction;
++  bool mDumpToStdout;
+ 
+   enum {
+     eUnknown,
+     eInitialized,
+     eShuttingDown
+   } mStatus;
+ 
+   // This is used when Console is created and it's used only for JSM custom
+diff --git a/dom/console/ConsoleInstance.cpp b/dom/console/ConsoleInstance.cpp
+--- a/dom/console/ConsoleInstance.cpp
++++ b/dom/console/ConsoleInstance.cpp
+@@ -19,16 +19,23 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
+   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_END
+ 
+ ConsoleInstance::ConsoleInstance(const ConsoleInstanceOptions& aOptions)
+   : mConsole(new Console(nullptr))
+ {
+   mConsole->mConsoleID = aOptions.mConsoleID;
+   mConsole->mPassedInnerID = aOptions.mInnerID;
++
++  if (aOptions.mDump.WasPassed()) {
++    mConsole->mDumpFunction = &aOptions.mDump.Value();
++  } else {
++    // For historical reasons, ConsoleInstance prints messages on stdout.
++    mConsole->mDumpToStdout = true;
++  }
+ }
+ 
+ ConsoleInstance::~ConsoleInstance()
+ {}
+ 
+ JSObject*
+ ConsoleInstance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+ {
+diff --git a/dom/console/tests/console.jsm b/dom/console/tests/console.jsm
+--- a/dom/console/tests/console.jsm
++++ b/dom/console/tests/console.jsm
+@@ -1,16 +1,21 @@
+ /**
+  * Any copyright is dedicated to the Public Domain.
+  * http://creativecommons.org/publicdomain/zero/1.0/
+  */
+ this.EXPORTED_SYMBOLS = [ "ConsoleTest" ];
+ 
+ this.ConsoleTest = {
+-  go: function() {
++  go: function(dumpFunction) {
+     console.log("Hello world!");
+     console.createInstance().log("Hello world!");
+-    console.createInstance({
++
++    let c = console.createInstance({
+       consoleID: "wow",
+       innerID: "CUSTOM INNER",
+-    }).log("Hello world!");
++      dump: dumpFunction,
++    });
++
++    c.log("Hello world!");
++    c.trace("Hello world!");
+   }
+ };
+diff --git a/dom/console/tests/test_jsm.xul b/dom/console/tests/test_jsm.xul
+--- a/dom/console/tests/test_jsm.xul
++++ b/dom/console/tests/test_jsm.xul
+@@ -12,54 +12,61 @@
+   <script type="application/javascript"
+           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
+ 
+   <script type="application/javascript">
+   <![CDATA[
+ 
+ const JSM = "chrome://mochitests/content/chrome/dom/console/tests/console.jsm";
+ 
++let dumpCalled = 0;
++function dumpFunction(msg) {
++  dump("Message received: " + msg); // Just for debugging
++  dumpCalled++;
++}
++
+ function consoleListener() {
+   SpecialPowers.addObserver(this, "console-api-log-event");
+ }
+ 
+ consoleListener.prototype  = {
+   count: 0,
+ 
+   observe: function(aSubject, aTopic, aData) {
+     if (aTopic == "console-api-log-event") {
+       var obj = aSubject.wrappedJSObject;
+       if (obj.innerID == JSM) {
+         is(obj.ID, "jsm", "ID and InnerID are correctly set.");
+-        is (obj.arguments[0], "Hello world!", "Message matches");
++        is(obj.arguments[0], "Hello world!", "Message matches");
+         is(obj.consoleID, "", "No consoleID for console API");
+ 
+         // We want to see 2 messages from this innerID, the first is generated
+         // by console.log, the second one from createInstance().log();
+         ++this.count;
+       } else if (obj.innerID = "CUSTOM INNER") {
+         is(obj.ID, "jsm", "ID and InnerID are correctly set.");
+-        is (obj.arguments[0], "Hello world!", "Message matches");
++        is(obj.arguments[0], "Hello world!", "Message matches");
+         is(obj.consoleID, "wow", "consoleID is set by consoleInstance");
+         ++this.count;
+       }
+ 
+-      if (this.count == 3) {
++      if (this.count == 4) {
++        is(dumpCalled, 2, "Dump has been called!");
+         SpecialPowers.removeObserver(this, "console-api-log-event");
+         SimpleTest.finish();
+       }
+     }
+   }
+ }
+ function test() {
+   SimpleTest.waitForExplicitFinish();
+ 
+   var cl = new consoleListener();
+   Components.utils.import(JSM);
+-  ConsoleTest.go();
++  ConsoleTest.go(dumpFunction);
+ }
+ 
+   ]]>
+   </script>
+ 
+   <body xmlns="http://www.w3.org/1999/xhtml">
+   </body>
+ </window>
+diff --git a/dom/webidl/Console.webidl b/dom/webidl/Console.webidl
+--- a/dom/webidl/Console.webidl
++++ b/dom/webidl/Console.webidl
+@@ -149,17 +149,19 @@ interface ConsoleInstance {
+ 
+   void _exception(any... data);
+   void timeStamp(optional any data);
+ 
+   void profile(any... data);
+   void profileEnd(any... data);
+ };
+ 
++callback ConsoleInstanceDumpCallback = void (DOMString message);
++
+ dictionary ConsoleInstanceOptions {
++  ConsoleInstanceDumpCallback dump;
+ /* TODO:
+-  boolean dump = false;
+   DOMString prefix = "";
+   DOMString maxLogLevel = "";
+ */
+   DOMString innerID = "";
+   DOMString consoleID = "";
+ };

+ 157 - 0
mozilla-release/patches/1425574-5-59a1.patch

@@ -0,0 +1,157 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1515089984 -3600
+# Node ID 69dc8f8bea227722540cab47773f97a4fbb49e04
+# Parent  3409e99041cc282582428f0769fa113421bb4709
+Bug 1425574 - Fill the feature gap between Console.jsm and Console API - part 5 - prefix, r=smaug, r=bgrins
+
+diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp
+--- a/dom/console/Console.cpp
++++ b/dom/console/Console.cpp
+@@ -2560,16 +2560,21 @@ Console::MaybeExecuteDumpFunction(JSCont
+     return;
+   }
+ 
+   nsAutoString message;
+   message.AssignLiteral("console.");
+   message.Append(aMethodName);
+   message.AppendLiteral(": ");
+ 
++  if (!mDumpPrefix.IsEmpty()) {
++    message.Append(mDumpPrefix);
++    message.AppendLiteral(": ");
++  }
++
+   for (uint32_t i = 0; i < aData.Length(); ++i) {
+     JS::Rooted<JS::Value> v(aCx, aData[i]);
+     JS::Rooted<JSString*> jsString(aCx, JS_ValueToSource(aCx, v));
+     if (!jsString) {
+       continue;
+     }
+ 
+     nsAutoJSString string;
+@@ -2593,16 +2598,21 @@ Console::MaybeExecuteDumpFunctionForTrac
+ {
+   if (!aStack || (!mDumpFunction && !mDumpToStdout)) {
+     return;
+   }
+ 
+   nsAutoString message;
+   message.AssignLiteral("console.trace:\n");
+ 
++  if (!mDumpPrefix.IsEmpty()) {
++    message.Append(mDumpPrefix);
++    message.AppendLiteral(": ");
++  }
++
+   nsCOMPtr<nsIStackFrame> stack(aStack);
+ 
+   while (stack) {
+     nsAutoString filename;
+     stack->GetFilename(aCx, filename);
+ 
+     message.Append(filename);
+     message.AppendLiteral(" ");
+diff --git a/dom/console/Console.h b/dom/console/Console.h
+--- a/dom/console/Console.h
++++ b/dom/console/Console.h
+@@ -428,16 +428,17 @@ private:
+   uint64_t mOuterID;
+   uint64_t mInnerID;
+ 
+   // Set only by ConsoleInstance:
+   nsString mConsoleID;
+   nsString mPassedInnerID;
+   RefPtr<ConsoleInstanceDumpCallback> mDumpFunction;
+   bool mDumpToStdout;
++  nsString mDumpPrefix;
+ 
+   enum {
+     eUnknown,
+     eInitialized,
+     eShuttingDown
+   } mStatus;
+ 
+   // This is used when Console is created and it's used only for JSM custom
+diff --git a/dom/console/ConsoleInstance.cpp b/dom/console/ConsoleInstance.cpp
+--- a/dom/console/ConsoleInstance.cpp
++++ b/dom/console/ConsoleInstance.cpp
+@@ -26,16 +26,18 @@ ConsoleInstance::ConsoleInstance(const C
+   mConsole->mPassedInnerID = aOptions.mInnerID;
+ 
+   if (aOptions.mDump.WasPassed()) {
+     mConsole->mDumpFunction = &aOptions.mDump.Value();
+   } else {
+     // For historical reasons, ConsoleInstance prints messages on stdout.
+     mConsole->mDumpToStdout = true;
+   }
++
++  mConsole->mDumpPrefix = aOptions.mPrefix;
+ }
+ 
+ ConsoleInstance::~ConsoleInstance()
+ {}
+ 
+ JSObject*
+ ConsoleInstance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+ {
+diff --git a/dom/console/tests/console.jsm b/dom/console/tests/console.jsm
+--- a/dom/console/tests/console.jsm
++++ b/dom/console/tests/console.jsm
+@@ -8,14 +8,15 @@ this.ConsoleTest = {
+   go: function(dumpFunction) {
+     console.log("Hello world!");
+     console.createInstance().log("Hello world!");
+ 
+     let c = console.createInstance({
+       consoleID: "wow",
+       innerID: "CUSTOM INNER",
+       dump: dumpFunction,
++      prefix: "_PREFIX_";
+     });
+ 
+     c.log("Hello world!");
+     c.trace("Hello world!");
+   }
+ };
+diff --git a/dom/console/tests/test_jsm.xul b/dom/console/tests/test_jsm.xul
+--- a/dom/console/tests/test_jsm.xul
++++ b/dom/console/tests/test_jsm.xul
+@@ -14,16 +14,17 @@
+ 
+   <script type="application/javascript">
+   <![CDATA[
+ 
+ const JSM = "chrome://mochitests/content/chrome/dom/console/tests/console.jsm";
+ 
+ let dumpCalled = 0;
+ function dumpFunction(msg) {
++  ok(msg.indexOf("_PREFIX_") != -1, "we have a prefix");
+   dump("Message received: " + msg); // Just for debugging
+   dumpCalled++;
+ }
+ 
+ function consoleListener() {
+   SpecialPowers.addObserver(this, "console-api-log-event");
+ }
+ 
+diff --git a/dom/webidl/Console.webidl b/dom/webidl/Console.webidl
+--- a/dom/webidl/Console.webidl
++++ b/dom/webidl/Console.webidl
+@@ -153,15 +153,15 @@ interface ConsoleInstance {
+   void profile(any... data);
+   void profileEnd(any... data);
+ };
+ 
+ callback ConsoleInstanceDumpCallback = void (DOMString message);
+ 
+ dictionary ConsoleInstanceOptions {
+   ConsoleInstanceDumpCallback dump;
++  DOMString prefix = "";
+ /* TODO:
+-  DOMString prefix = "";
+   DOMString maxLogLevel = "";
+ */
+   DOMString innerID = "";
+   DOMString consoleID = "";
+ };

+ 25 - 0
mozilla-release/patches/1425574-6-59a1.patch

@@ -0,0 +1,25 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1515089984 -3600
+# Node ID 0882de3b96b9e39a5075f4c2885ff9a8a2ac0d8b
+# Parent  87e5b25fe3c17491a5997bd7e851c4331e9d3f5b
+Bug 1425574 - Fill the feature gap between Console.jsm and Console API - part 6 - no maxLogLevel support, r=smaug
+
+diff --git a/dom/webidl/Console.webidl b/dom/webidl/Console.webidl
+--- a/dom/webidl/Console.webidl
++++ b/dom/webidl/Console.webidl
+@@ -154,14 +154,11 @@ interface ConsoleInstance {
+   void profileEnd(any... data);
+ };
+ 
+ callback ConsoleInstanceDumpCallback = void (DOMString message);
+ 
+ dictionary ConsoleInstanceOptions {
+   ConsoleInstanceDumpCallback dump;
+   DOMString prefix = "";
+-/* TODO:
+-  DOMString maxLogLevel = "";
+-*/
+   DOMString innerID = "";
+   DOMString consoleID = "";
+ };

+ 148 - 0
mozilla-release/patches/1425574-7-59a1.patch

@@ -0,0 +1,148 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1515089984 -3600
+# Node ID 9f44d89eda685123154dfb9a7ce5736a57b72429
+# Parent  f6d3617953505b1b2780294bc8fa00eeff5fda32
+Bug 1425574 - Fill the feature gap between Console.jsm and Console API - part 7 - Console active, r=smaug
+
+diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp
+--- a/dom/console/Console.cpp
++++ b/dom/console/Console.cpp
+@@ -817,16 +817,17 @@ Console::Create(nsPIDOMWindowInner* aWin
+   return console.forget();
+ }
+ 
+ Console::Console(nsPIDOMWindowInner* aWindow)
+   : mWindow(aWindow)
+   , mOuterID(0)
+   , mInnerID(0)
+   , mDumpToStdout(false)
++  , mChromeInstance(false)
+   , mStatus(eUnknown)
+   , mCreationTimeStamp(TimeStamp::Now())
+ {
+   if (mWindow) {
+     MOZ_ASSERT(mWindow->IsInnerWindow());
+     mInnerID = mWindow->WindowID();
+ 
+     // Without outerwindow any console message coming from this object will not
+@@ -1066,22 +1067,33 @@ Console::ProfileMethod(const GlobalObjec
+   if (!console) {
+     return;
+   }
+ 
+   JSContext* cx = aGlobal.Context();
+   console->ProfileMethodInternal(cx, aAction, aData);
+ }
+ 
++bool
++Console::IsEnabled(JSContext* aCx) const
++{
++  // Console is always enabled if it is a custom Chrome-Only instance.
++  if (mChromeInstance) {
++    return true;
++  }
++
++  // Make all Console API no-op if DevTools aren't enabled.
++  return nsContentUtils::DevToolsEnabled(aCx);
++}
++
+ void
+ Console::ProfileMethodInternal(JSContext* aCx, const nsAString& aAction,
+                                const Sequence<JS::Value>& aData)
+ {
+-  // Make all Console API no-op if DevTools aren't enabled.
+-  if (!nsContentUtils::DevToolsEnabled(aCx)) {
++  if (!IsEnabled(aCx)) {
+     return;
+   }
+ 
+   MaybeExecuteDumpFunction(aCx, aAction, aData);
+ 
+   if (!NS_IsMainThread()) {
+     // Here we are in a worker thread.
+     RefPtr<ConsoleProfileRunnable> runnable =
+@@ -1207,18 +1219,17 @@ Console::Method(const GlobalObject& aGlo
+                           aData);
+ }
+ 
+ void
+ Console::MethodInternal(JSContext* aCx, MethodName aMethodName,
+                         const nsAString& aMethodString,
+                         const Sequence<JS::Value>& aData)
+ {
+-  // Make all Console API no-op if DevTools aren't enabled.
+-  if (!nsContentUtils::DevToolsEnabled(aCx)) {
++  if (!IsEnabled(aCx)) {
+     return;
+   }
+ 
+   AssertIsOnOwningThread();
+ 
+   RefPtr<ConsoleCallData> callData(new ConsoleCallData());
+ 
+   ClearException ce(aCx);
+diff --git a/dom/console/Console.h b/dom/console/Console.h
+--- a/dom/console/Console.h
++++ b/dom/console/Console.h
+@@ -393,16 +393,19 @@ private:
+                            const Sequence<JS::Value>& aData);
+ 
+   void
+   MaybeExecuteDumpFunctionForTrace(JSContext* aCx, nsIStackFrame* aStack);
+ 
+   void
+   ExecuteDumpFunction(const nsAString& aMessage);
+ 
++  bool
++  IsEnabled(JSContext* aCx) const;
++
+   // All these nsCOMPtr are touched on main thread only.
+   nsCOMPtr<nsPIDOMWindowInner> mWindow;
+   nsCOMPtr<nsIConsoleAPIStorage> mStorage;
+   RefPtr<JSObjectHolder> mSandbox;
+ 
+   // Touched on the owner thread.
+   nsDataHashtable<nsStringHashKey, DOMHighResTimeStamp> mTimerRegistry;
+   nsDataHashtable<nsStringHashKey, uint32_t> mCounterRegistry;
+@@ -429,16 +432,17 @@ private:
+   uint64_t mInnerID;
+ 
+   // Set only by ConsoleInstance:
+   nsString mConsoleID;
+   nsString mPassedInnerID;
+   RefPtr<ConsoleInstanceDumpCallback> mDumpFunction;
+   bool mDumpToStdout;
+   nsString mDumpPrefix;
++  bool mChromeInstance;
+ 
+   enum {
+     eUnknown,
+     eInitialized,
+     eShuttingDown
+   } mStatus;
+ 
+   // This is used when Console is created and it's used only for JSM custom
+diff --git a/dom/console/ConsoleInstance.cpp b/dom/console/ConsoleInstance.cpp
+--- a/dom/console/ConsoleInstance.cpp
++++ b/dom/console/ConsoleInstance.cpp
+@@ -28,16 +28,19 @@ ConsoleInstance::ConsoleInstance(const C
+   if (aOptions.mDump.WasPassed()) {
+     mConsole->mDumpFunction = &aOptions.mDump.Value();
+   } else {
+     // For historical reasons, ConsoleInstance prints messages on stdout.
+     mConsole->mDumpToStdout = true;
+   }
+ 
+   mConsole->mDumpPrefix = aOptions.mPrefix;
++
++  // Let's inform that this is a custom instance.
++  mConsole->mChromeInstance = true;
+ }
+ 
+ ConsoleInstance::~ConsoleInstance()
+ {}
+ 
+ JSObject*
+ ConsoleInstance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+ {

+ 459 - 0
mozilla-release/patches/1425574-8-59a1.patch

@@ -0,0 +1,459 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1515089984 -3600
+# Node ID 7a4e812ee5adc626ba19828f770d720f0b9db9cd
+# Parent  b922efc65bbb8b02b8abc57a0fc135c3bdace741
+Bug 1425574 - Fill the feature gap between Console.jsm and Console API - part 8 - maxLogLevel, r=smaug
+
+diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp
+--- a/dom/console/Console.cpp
++++ b/dom/console/Console.cpp
+@@ -661,19 +661,21 @@ private:
+ 
+   RefPtr<ConsoleCallData> mCallData;
+ };
+ 
+ // This runnable calls ProfileMethod() on the console on the main-thread.
+ class ConsoleProfileRunnable final : public ConsoleRunnable
+ {
+ public:
+-  ConsoleProfileRunnable(Console* aConsole, const nsAString& aAction,
++  ConsoleProfileRunnable(Console* aConsole, Console::MethodName aName,
++                         const nsAString& aAction,
+                          const Sequence<JS::Value>& aArguments)
+     : ConsoleRunnable(aConsole)
++    , mName(aName)
+     , mAction(aAction)
+     , mArguments(aArguments)
+   {
+     MOZ_ASSERT(aConsole);
+   }
+ 
+ private:
+   bool
+@@ -744,23 +746,24 @@ private:
+         return;
+       }
+ 
+       if (!arguments.AppendElement(value, fallible)) {
+         return;
+       }
+     }
+ 
+-    mConsole->ProfileMethodInternal(aCx, mAction, arguments);
++    mConsole->ProfileMethodInternal(aCx, mName, mAction, arguments);
+   }
+ 
+   virtual void
+   ReleaseData() override
+   {}
+ 
++  Console::MethodName mName;
+   nsString mAction;
+ 
+   // This is a reference of the sequence of arguments we receive from the DOM
+   // bindings and it's rooted by them. It's only used on the owning thread in
+   // PreDispatch().
+   const Sequence<JS::Value>& mArguments;
+ };
+ 
+@@ -818,16 +821,17 @@ Console::Create(nsPIDOMWindowInner* aWin
+ }
+ 
+ Console::Console(nsPIDOMWindowInner* aWindow)
+   : mWindow(aWindow)
+   , mOuterID(0)
+   , mInnerID(0)
+   , mDumpToStdout(false)
+   , mChromeInstance(false)
++  , mMaxLogLevel(ConsoleLogLevel::All)
+   , mStatus(eUnknown)
+   , mCreationTimeStamp(TimeStamp::Now())
+ {
+   if (mWindow) {
+     MOZ_ASSERT(mWindow->IsInnerWindow());
+     mInnerID = mWindow->WindowID();
+ 
+     // Without outerwindow any console message coming from this object will not
+@@ -1044,65 +1048,72 @@ Console::TimeStamp(const GlobalObject& a
+   }
+ 
+   Method(aGlobal, MethodTimeStamp, NS_LITERAL_STRING("timeStamp"), data);
+ }
+ 
+ /* static */ void
+ Console::Profile(const GlobalObject& aGlobal, const Sequence<JS::Value>& aData)
+ {
+-  ProfileMethod(aGlobal, NS_LITERAL_STRING("profile"), aData);
++  ProfileMethod(aGlobal, MethodProfile, NS_LITERAL_STRING("profile"), aData);
+ }
+ 
+ /* static */ void
+ Console::ProfileEnd(const GlobalObject& aGlobal,
+                     const Sequence<JS::Value>& aData)
+ {
+-  ProfileMethod(aGlobal, NS_LITERAL_STRING("profileEnd"), aData);
++  ProfileMethod(aGlobal, MethodProfileEnd, NS_LITERAL_STRING("profileEnd"),
++                aData);
+ }
+ 
+ /* static */ void
+-Console::ProfileMethod(const GlobalObject& aGlobal, const nsAString& aAction,
++Console::ProfileMethod(const GlobalObject& aGlobal, MethodName aName,
++                       const nsAString& aAction,
+                        const Sequence<JS::Value>& aData)
+ {
+   RefPtr<Console> console = GetConsole(aGlobal);
+   if (!console) {
+     return;
+   }
+ 
+   JSContext* cx = aGlobal.Context();
+-  console->ProfileMethodInternal(cx, aAction, aData);
++  console->ProfileMethodInternal(cx, aName, aAction, aData);
+ }
+ 
+ bool
+ Console::IsEnabled(JSContext* aCx) const
+ {
+   // Console is always enabled if it is a custom Chrome-Only instance.
+   if (mChromeInstance) {
+     return true;
+   }
+ 
+   // Make all Console API no-op if DevTools aren't enabled.
+   return nsContentUtils::DevToolsEnabled(aCx);
+ }
+ 
+ void
+-Console::ProfileMethodInternal(JSContext* aCx, const nsAString& aAction,
++Console::ProfileMethodInternal(JSContext* aCx, MethodName aMethodName,
++                               const nsAString& aAction,
+                                const Sequence<JS::Value>& aData)
+ {
+   if (!IsEnabled(aCx)) {
+     return;
+   }
+ 
++  if (!ShouldProceed(aMethodName)) {
++    return;
++  }
++
+   MaybeExecuteDumpFunction(aCx, aAction, aData);
+ 
+   if (!NS_IsMainThread()) {
+     // Here we are in a worker thread.
+     RefPtr<ConsoleProfileRunnable> runnable =
+-      new ConsoleProfileRunnable(this, aAction, aData);
++      new ConsoleProfileRunnable(this, aMethodName, aAction, aData);
+ 
+     runnable->Dispatch(aCx);
+     return;
+   }
+ 
+   ClearException ce(aCx);
+ 
+   RootedDictionary<ConsoleProfileEvent> event(aCx);
+@@ -1223,16 +1234,20 @@ void
+ Console::MethodInternal(JSContext* aCx, MethodName aMethodName,
+                         const nsAString& aMethodString,
+                         const Sequence<JS::Value>& aData)
+ {
+   if (!IsEnabled(aCx)) {
+     return;
+   }
+ 
++  if (!ShouldProceed(aMethodName)) {
++    return;
++  }
++
+   AssertIsOnOwningThread();
+ 
+   RefPtr<ConsoleCallData> callData(new ConsoleCallData());
+ 
+   ClearException ce(aCx);
+ 
+   if (NS_WARN_IF(!callData->Initialize(aCx, aMethodName, aMethodString,
+                                        aData, this))) {
+@@ -2663,10 +2678,79 @@ Console::ExecuteDumpFunction(const nsASt
+   MOZ_LOG(nsContentUtils::DOMDumpLog(), LogLevel::Debug, ("%s", str.get()));
+ #ifdef ANDROID
+   __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", str.get());
+ #endif
+   fputs(str.get(), stdout);
+   fflush(stdout);
+ }
+ 
++bool
++Console::ShouldProceed(MethodName aName) const
++{
++  return WebIDLLogLevelToInteger(mMaxLogLevel) <=
++           InternalLogLevelToInteger(aName);
++}
++
++uint32_t
++Console::WebIDLLogLevelToInteger(ConsoleLogLevel aLevel) const
++{
++  switch (aLevel) {
++    case ConsoleLogLevel::All: return 0;
++    case ConsoleLogLevel::Debug: return 2;
++    case ConsoleLogLevel::Log: return 3;
++    case ConsoleLogLevel::Info: return 3;
++    case ConsoleLogLevel::Clear: return 3;
++    case ConsoleLogLevel::Trace: return 3;
++    case ConsoleLogLevel::TimeEnd: return 3;
++    case ConsoleLogLevel::Time: return 3;
++    case ConsoleLogLevel::Group: return 3;
++    case ConsoleLogLevel::GroupEnd: return 3;
++    case ConsoleLogLevel::Profile: return 3;
++    case ConsoleLogLevel::ProfileEnd: return 3;
++    case ConsoleLogLevel::Dir: return 3;
++    case ConsoleLogLevel::Dirxml: return 3;
++    case ConsoleLogLevel::Warn: return 4;
++    case ConsoleLogLevel::Error: return 5;
++    case ConsoleLogLevel::Off: return UINT32_MAX;
++    default:
++      MOZ_CRASH("ConsoleLogLevel is out of sync with the Console implementation!");
++      return 0;
++  }
++
++  return 0;
++}
++
++uint32_t
++Console::InternalLogLevelToInteger(MethodName aName) const
++{
++  switch (aName) {
++    case MethodLog: return 3;
++    case MethodInfo: return 3;
++    case MethodWarn: return 4;
++    case MethodError: return 5;
++    case MethodException: return 5;
++    case MethodDebug: return 2;
++    case MethodTable: return 3;
++    case MethodTrace: return 3;
++    case MethodDir: return 3;
++    case MethodDirxml: return 3;
++    case MethodGroup: return 3;
++    case MethodGroupCollapsed: return 3;
++    case MethodGroupEnd: return 3;
++    case MethodTime: return 3;
++    case MethodTimeEnd: return 3;
++    case MethodTimeStamp: return 3;
++    case MethodAssert: return 3;
++    case MethodCount: return 3;
++    case MethodClear: return 3;
++    case MethodProfile: return 3;
++    case MethodProfileEnd: return 3;
++    default:
++      MOZ_CRASH("MethodName is out of sync with the Console implementation!");
++      return 0;
++  }
++
++  return 0;
++}
++
+ } // namespace dom
+ } // namespace mozilla
+diff --git a/dom/console/Console.h b/dom/console/Console.h
+--- a/dom/console/Console.h
++++ b/dom/console/Console.h
+@@ -2,18 +2,17 @@
+ /* 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_Console_h
+ #define mozilla_dom_Console_h
+ 
+-#include "mozilla/dom/BindingDeclarations.h"
+-#include "mozilla/ErrorResult.h"
++#include "mozilla/dom/ConsoleBinding.h"
+ #include "mozilla/JSObjectHolder.h"
+ #include "mozilla/TimeStamp.h"
+ #include "nsCycleCollectionParticipant.h"
+ #include "nsDataHashtable.h"
+ #include "nsHashKeys.h"
+ #include "nsIObserver.h"
+ #include "nsWeakReference.h"
+ #include "nsDOMNavigationTiming.h"
+@@ -28,19 +27,16 @@ namespace dom {
+ 
+ class AnyCallback;
+ class ConsoleCallData;
+ class ConsoleInstance;
+ class ConsoleInstanceDumpCallback;
+ class ConsoleRunnable;
+ class ConsoleCallDataRunnable;
+ class ConsoleProfileRunnable;
+-struct ConsoleInstanceOptions;
+-struct ConsoleTimerError;
+-struct ConsoleStackEntry;
+ 
+ class Console final : public nsIObserver
+                     , public nsSupportsWeakReference
+ {
+ public:
+   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Console, nsIObserver)
+   NS_DECL_NSIOBSERVER
+@@ -157,31 +153,34 @@ private:
+     MethodGroup,
+     MethodGroupCollapsed,
+     MethodGroupEnd,
+     MethodTime,
+     MethodTimeEnd,
+     MethodTimeStamp,
+     MethodAssert,
+     MethodCount,
+-    MethodClear
++    MethodClear,
++    MethodProfile,
++    MethodProfileEnd,
+   };
+ 
+   static already_AddRefed<Console>
+   GetConsole(const GlobalObject& aGlobal);
+ 
+   static already_AddRefed<Console>
+   GetConsoleInternal(const GlobalObject& aGlobal, ErrorResult &aRv);
+ 
+   static void
+-  ProfileMethod(const GlobalObject& aGlobal, const nsAString& aAction,
+-                const Sequence<JS::Value>& aData);
++  ProfileMethod(const GlobalObject& aGlobal, MethodName aName,
++                const nsAString& aAction, const Sequence<JS::Value>& aData);
+ 
+   void
+-  ProfileMethodInternal(JSContext* aCx, const nsAString& aAction,
++  ProfileMethodInternal(JSContext* aCx, MethodName aName,
++                        const nsAString& aAction,
+                         const Sequence<JS::Value>& aData);
+ 
+   static void
+   Method(const GlobalObject& aGlobal, MethodName aName,
+          const nsAString& aString, const Sequence<JS::Value>& aData);
+ 
+   void
+   MethodInternal(JSContext* aCx, MethodName aName,
+@@ -396,16 +395,25 @@ private:
+   MaybeExecuteDumpFunctionForTrace(JSContext* aCx, nsIStackFrame* aStack);
+ 
+   void
+   ExecuteDumpFunction(const nsAString& aMessage);
+ 
+   bool
+   IsEnabled(JSContext* aCx) const;
+ 
++  bool
++  ShouldProceed(MethodName aName) const;
++
++  uint32_t
++  WebIDLLogLevelToInteger(ConsoleLogLevel aLevel) const;
++
++  uint32_t
++  InternalLogLevelToInteger(MethodName aName) const;
++
+   // All these nsCOMPtr are touched on main thread only.
+   nsCOMPtr<nsPIDOMWindowInner> mWindow;
+   nsCOMPtr<nsIConsoleAPIStorage> mStorage;
+   RefPtr<JSObjectHolder> mSandbox;
+ 
+   // Touched on the owner thread.
+   nsDataHashtable<nsStringHashKey, DOMHighResTimeStamp> mTimerRegistry;
+   nsDataHashtable<nsStringHashKey, uint32_t> mCounterRegistry;
+@@ -433,16 +441,17 @@ private:
+ 
+   // Set only by ConsoleInstance:
+   nsString mConsoleID;
+   nsString mPassedInnerID;
+   RefPtr<ConsoleInstanceDumpCallback> mDumpFunction;
+   bool mDumpToStdout;
+   nsString mDumpPrefix;
+   bool mChromeInstance;
++  ConsoleLogLevel mMaxLogLevel;
+ 
+   enum {
+     eUnknown,
+     eInitialized,
+     eShuttingDown
+   } mStatus;
+ 
+   // This is used when Console is created and it's used only for JSM custom
+diff --git a/dom/console/ConsoleInstance.cpp b/dom/console/ConsoleInstance.cpp
+--- a/dom/console/ConsoleInstance.cpp
++++ b/dom/console/ConsoleInstance.cpp
+@@ -31,16 +31,20 @@ ConsoleInstance::ConsoleInstance(const C
+     // For historical reasons, ConsoleInstance prints messages on stdout.
+     mConsole->mDumpToStdout = true;
+   }
+ 
+   mConsole->mDumpPrefix = aOptions.mPrefix;
+ 
+   // Let's inform that this is a custom instance.
+   mConsole->mChromeInstance = true;
++
++  if (aOptions.mMaxLogLevel.WasPassed()) {
++    mConsole->mMaxLogLevel = aOptions.mMaxLogLevel.Value();
++  }
+ }
+ 
+ ConsoleInstance::~ConsoleInstance()
+ {}
+ 
+ JSObject*
+ ConsoleInstance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+ {
+@@ -106,23 +110,25 @@ ConsoleInstance::TimeStamp(JSContext* aC
+ 
+   mConsole->MethodInternal(aCx, Console::MethodTimeStamp,
+                            NS_LITERAL_STRING("timeStamp"), data);
+ }
+ 
+ void
+ ConsoleInstance::Profile(JSContext* aCx, const Sequence<JS::Value>& aData)
+ {
+-  mConsole->ProfileMethodInternal(aCx, NS_LITERAL_STRING("profile"), aData);
++  mConsole->ProfileMethodInternal(aCx, Console::MethodProfile,
++                                  NS_LITERAL_STRING("profile"), aData);
+ }
+ 
+ void
+ ConsoleInstance::ProfileEnd(JSContext* aCx, const Sequence<JS::Value>& aData)
+ {
+-  mConsole->ProfileMethodInternal(aCx, NS_LITERAL_STRING("profileEnd"), aData);
++  mConsole->ProfileMethodInternal(aCx, Console::MethodProfileEnd,
++                                  NS_LITERAL_STRING("profileEnd"), aData);
+ }
+ 
+ void
+ ConsoleInstance::Assert(JSContext* aCx, bool aCondition,
+                         const Sequence<JS::Value>& aData)
+ {
+   if (!aCondition) {
+     mConsole->MethodInternal(aCx, Console::MethodAssert,
+diff --git a/dom/webidl/Console.webidl b/dom/webidl/Console.webidl
+--- a/dom/webidl/Console.webidl
++++ b/dom/webidl/Console.webidl
+@@ -151,14 +151,20 @@ interface ConsoleInstance {
+   void timeStamp(optional any data);
+ 
+   void profile(any... data);
+   void profileEnd(any... data);
+ };
+ 
+ callback ConsoleInstanceDumpCallback = void (DOMString message);
+ 
++enum ConsoleLogLevel {
++  "all", "debug", "log", "info", "clear", "trace", "timeEnd", "time", "group",
++  "groupEnd", "profile", "profileEnd", "dir", "dirxml", "warn", "error", "off"
++};
++
+ dictionary ConsoleInstanceOptions {
+   ConsoleInstanceDumpCallback dump;
+   DOMString prefix = "";
+   DOMString innerID = "";
+   DOMString consoleID = "";
++  ConsoleLogLevel maxLogLevel;
+ };

+ 190 - 0
mozilla-release/patches/1425574-9-59a1.patch

@@ -0,0 +1,190 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1515089984 -3600
+# Node ID edb150980a7f29cb7e7125b4805964e7b094c503
+# Parent  30420e3090bb207a8892703604ed3108fc3ba9b4
+Bug 1425574 - Fill the feature gap between Console.jsm and Console API - part 9 - maxLogLevel pref, r=smaug, r=bgrins
+
+diff --git a/dom/console/ConsoleInstance.cpp b/dom/console/ConsoleInstance.cpp
+--- a/dom/console/ConsoleInstance.cpp
++++ b/dom/console/ConsoleInstance.cpp
+@@ -14,16 +14,44 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Co
+ 
+ NS_IMPL_CYCLE_COLLECTING_ADDREF(ConsoleInstance)
+ NS_IMPL_CYCLE_COLLECTING_RELEASE(ConsoleInstance)
+ 
+ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ConsoleInstance)
+   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_END
+ 
++namespace {
++
++ConsoleLogLevel
++PrefToValue(const nsCString& aPref)
++{
++  if (!NS_IsMainThread()) {
++    NS_WARNING("Console.maxLogLevelPref is not supported on workers!");
++    return ConsoleLogLevel::All;
++  }
++
++  nsAutoCString value;
++  nsresult rv = Preferences::GetCString(aPref.get(), value);
++  if (NS_WARN_IF(NS_FAILED(rv))) {
++    return ConsoleLogLevel::All;
++  }
++
++  int index = FindEnumStringIndexImpl(value.get(), value.Length(),
++                                      ConsoleLogLevelValues::strings);
++  if (NS_WARN_IF(index < 0)) {
++    return ConsoleLogLevel::All;
++  }
++
++  MOZ_ASSERT(index < (int)ConsoleLogLevel::EndGuard_);
++  return static_cast<ConsoleLogLevel>(index);
++}
++
++} // anonymous
++
+ ConsoleInstance::ConsoleInstance(const ConsoleInstanceOptions& aOptions)
+   : mConsole(new Console(nullptr))
+ {
+   mConsole->mConsoleID = aOptions.mConsoleID;
+   mConsole->mPassedInnerID = aOptions.mInnerID;
+ 
+   if (aOptions.mDump.WasPassed()) {
+     mConsole->mDumpFunction = &aOptions.mDump.Value();
+@@ -35,16 +63,21 @@ ConsoleInstance::ConsoleInstance(const C
+   mConsole->mDumpPrefix = aOptions.mPrefix;
+ 
+   // Let's inform that this is a custom instance.
+   mConsole->mChromeInstance = true;
+ 
+   if (aOptions.mMaxLogLevel.WasPassed()) {
+     mConsole->mMaxLogLevel = aOptions.mMaxLogLevel.Value();
+   }
++
++  if (!aOptions.mMaxLogLevelPref.IsEmpty()) {
++    mConsole->mMaxLogLevel =
++      PrefToValue(NS_ConvertUTF16toUTF8(aOptions.mMaxLogLevelPref));
++  }
+ }
+ 
+ ConsoleInstance::~ConsoleInstance()
+ {}
+ 
+ JSObject*
+ ConsoleInstance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+ {
+diff --git a/dom/console/tests/console.jsm b/dom/console/tests/console.jsm
+--- a/dom/console/tests/console.jsm
++++ b/dom/console/tests/console.jsm
+@@ -8,15 +8,20 @@ this.ConsoleTest = {
+   go: function(dumpFunction) {
+     console.log("Hello world!");
+     console.createInstance().log("Hello world!");
+ 
+     let c = console.createInstance({
+       consoleID: "wow",
+       innerID: "CUSTOM INNER",
+       dump: dumpFunction,
+-      prefix: "_PREFIX_";
++      prefix: "_PREFIX_",
+     });
+ 
+     c.log("Hello world!");
+     c.trace("Hello world!");
++
++    console.createInstance({ innerID: "LEVEL", maxLogLevel: "off" }).log("Invisible!");
++    console.createInstance({ innerID: "LEVEL",  maxLogLevel: "all" }).log("Hello world!");
++    console.createInstance({ innerID: "LEVEL", maxLogLevelPref: "foo.pref" }).log("Invisible!");
++    console.createInstance({ innerID: "LEVEL", maxLogLevelPref: "pref.test.console" }).log("Hello world!");
+   }
+ };
+diff --git a/dom/console/tests/test_jsm.xul b/dom/console/tests/test_jsm.xul
+--- a/dom/console/tests/test_jsm.xul
++++ b/dom/console/tests/test_jsm.xul
+@@ -37,37 +37,44 @@ consoleListener.prototype  = {
+       if (obj.innerID == JSM) {
+         is(obj.ID, "jsm", "ID and InnerID are correctly set.");
+         is(obj.arguments[0], "Hello world!", "Message matches");
+         is(obj.consoleID, "", "No consoleID for console API");
+ 
+         // We want to see 2 messages from this innerID, the first is generated
+         // by console.log, the second one from createInstance().log();
+         ++this.count;
+-      } else if (obj.innerID = "CUSTOM INNER") {
++      } else if (obj.innerID == "CUSTOM INNER") {
+         is(obj.ID, "jsm", "ID and InnerID are correctly set.");
+         is(obj.arguments[0], "Hello world!", "Message matches");
+         is(obj.consoleID, "wow", "consoleID is set by consoleInstance");
+         ++this.count;
++      } else if (obj.innerID == "LEVEL") {
++        // Nothing special... just we don't want to see 'invisible' messages.
++        is(obj.ID, "jsm", "ID and InnerID are correctly set.");
++        is(obj.arguments[0], "Hello world!", "Message matches");
++        ++this.count;
+       }
+ 
+       if (this.count == 4) {
+         is(dumpCalled, 2, "Dump has been called!");
+         SpecialPowers.removeObserver(this, "console-api-log-event");
+         SimpleTest.finish();
+       }
+     }
+   }
+ }
+ function test() {
+   SimpleTest.waitForExplicitFinish();
+ 
+-  var cl = new consoleListener();
+-  Components.utils.import(JSM);
+-  ConsoleTest.go(dumpFunction);
++  SpecialPowers.pushPrefEnv({set: [["pref.test.console", "log"]]}).then(() => {
++    var cl = new consoleListener();
++    Components.utils.import(JSM);
++    ConsoleTest.go(dumpFunction);
++  });
+ }
+ 
+   ]]>
+   </script>
+ 
+   <body xmlns="http://www.w3.org/1999/xhtml">
+   </body>
+ </window>
+diff --git a/dom/webidl/Console.webidl b/dom/webidl/Console.webidl
+--- a/dom/webidl/Console.webidl
++++ b/dom/webidl/Console.webidl
+@@ -157,14 +157,32 @@ interface ConsoleInstance {
+ callback ConsoleInstanceDumpCallback = void (DOMString message);
+ 
+ enum ConsoleLogLevel {
+   "all", "debug", "log", "info", "clear", "trace", "timeEnd", "time", "group",
+   "groupEnd", "profile", "profileEnd", "dir", "dirxml", "warn", "error", "off"
+ };
+ 
+ dictionary ConsoleInstanceOptions {
++  // An optional function to intercept all strings written to stdout.
+   ConsoleInstanceDumpCallback dump;
++
++  // An optional prefix string to be printed before the actual logged message.
+   DOMString prefix = "";
++
++  // An ID representing the source of the message. Normally the inner ID of a
++  // DOM window.
+   DOMString innerID = "";
++
++  // String identified for the console, this will be passed through the console
++  // notifications.
+   DOMString consoleID = "";
++
++  // Identifier that allows to filter which messages are logged based on their
++  // log level.
+   ConsoleLogLevel maxLogLevel;
++
++  // String pref name which contains the level to use for maxLogLevel. If the
++  // pref doesn't exist, gets removed or it is used in workers, the maxLogLevel
++  // will default to the value passed to this constructor (or "all" if it wasn't
++  // specified).
++  DOMString maxLogLevelPref = "";
+ };

+ 51 - 0
mozilla-release/patches/1425993-59a1.patch

@@ -0,0 +1,51 @@
+# HG changeset patch
+# User Ryan VanderMeulen <ryanvm@gmail.com>
+# Date 1515000949 18000
+# Node ID 4e60eefd78cc59b2ee913f4727e3cec2b3d2974e
+# Parent  34d0c3908556ece16a660a388ff1bf07c3311ff4
+Bug 1425993 - Make security violation events Nightly-only and update test expectations accordingly. r=smaug
+
+diff --git a/dom/tests/mochitest/general/test_interfaces.js b/dom/tests/mochitest/general/test_interfaces.js
+--- a/dom/tests/mochitest/general/test_interfaces.js
++++ b/dom/tests/mochitest/general/test_interfaces.js
+@@ -810,17 +810,17 @@ var interfaceNamesInGlobalScope =
+     "Screen",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "ScreenOrientation",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "ScriptProcessorNode",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "ScrollAreaEvent",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SecurityPolicyViolationEvent",
++    {name: "SecurityPolicyViolationEvent", release: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "Selection",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "ServiceWorker",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "ServiceWorkerContainer",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "ServiceWorkerRegistration",
+diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
+--- a/modules/libpref/init/all.js
++++ b/modules/libpref/init/all.js
+@@ -2627,17 +2627,17 @@ pref("security.checkloaduri", true);
+ pref("security.xpconnect.plugin.unrestricted", true);
+ // security-sensitive dialogs should delay button enabling. In milliseconds.
+ pref("security.dialog_enable_delay", 1000);
+ pref("security.notification_enable_delay", 500);
+ 
+ pref("security.csp.enable", true);
+ pref("security.csp.experimentalEnabled", false);
+ pref("security.csp.enableStrictDynamic", true);
+-#ifdef EARLY_BETA_OR_EARLIER
++#ifdef NIGHTLY_BUILD
+ pref("security.csp.enable_violation_events", true);
+ #else
+ pref("security.csp.enable_violation_events", false);
+ #endif
+ 
+ // Default Content Security Policy to apply to signed contents.
+ pref("security.signed_content.CSP.default", "script-src 'self'; style-src 'self'");
+ 

+ 37 - 42
mozilla-release/patches/1434686-4-60a1.patch

@@ -3,7 +3,7 @@
 # Date 1517512874 18000
 #      Thu Feb 01 14:21:14 2018 -0500
 # Node ID a3d5547b0b7f7aa9a3e5eaed7b3151cadff42334
-# Parent  2b9909e5c77064f367ae2188792564ef2453f396
+# Parent  9a7e6f40c118f72fdb7b9b2403d54b07f45e6752
 Bug 1434686 part 4.  Use IgnoreErrors() in dom/.  r=mystor
 
 MozReview-Commit-ID: GwVDrTLPTOb
@@ -77,7 +77,7 @@ new file mode 100644
 diff --git a/dom/base/nsContentAreaDragDrop.cpp b/dom/base/nsContentAreaDragDrop.cpp
 --- a/dom/base/nsContentAreaDragDrop.cpp
 +++ b/dom/base/nsContentAreaDragDrop.cpp
-@@ -54,16 +54,17 @@
+@@ -55,16 +55,17 @@
  #include "nsRange.h"
  #include "TabParent.h"
  #include "mozilla/dom/Element.h"
@@ -95,7 +95,7 @@ diff --git a/dom/base/nsContentAreaDragDrop.cpp b/dom/base/nsContentAreaDragDrop
                     nsIContent* aTarget,
                     nsIContent* aSelectionTargetNode,
                     bool aIsAltKeyPressed);
-@@ -347,20 +348,19 @@ DragDataProducer::GetNodeString(nsIConte
+@@ -348,20 +349,19 @@ DragDataProducer::GetNodeString(nsIConte
                                  nsAString & outNodeString)
  {
    nsCOMPtr<nsINode> node = inNode;
@@ -197,7 +197,7 @@ new file mode 100644
 diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h
 --- a/dom/base/nsGlobalWindow.h
 +++ b/dom/base/nsGlobalWindow.h
-@@ -1219,19 +1219,19 @@ public:
+@@ -1218,19 +1218,19 @@ public:
                         mozilla::ErrorResult& aError);
    void GetContent(JSContext* aCx,
                    JS::MutableHandle<JSObject*> aRetval,
@@ -269,33 +269,29 @@ new file mode 100644
 + {
 +   NS_ASSERT_OWNINGTHREAD(ClientSource);
 + 
-diff --git a/dom/console/Console.cpp.1434686.later b/dom/console/Console.cpp.1434686.later
-new file mode 100644
---- /dev/null
-+++ b/dom/console/Console.cpp.1434686.later
-@@ -0,0 +1,22 @@
-+--- Console.cpp
-++++ Console.cpp
-+@@ -2730,18 +2730,17 @@ Console::MaybeExecuteDumpFunctionForTrac
-+   message.AppendLiteral("\n");
-+   ExecuteDumpFunction(message);
-+ }
-+ 
-+ void
-+ Console::ExecuteDumpFunction(const nsAString& aMessage)
-+ {
-+   if (mDumpFunction) {
-+-    IgnoredErrorResult rv;
-+-    mDumpFunction->Call(aMessage, rv);
-++    mDumpFunction->Call(aMessage);
-+     return;
-+   }
-+ 
-+   NS_ConvertUTF16toUTF8 str(aMessage);
-+   MOZ_LOG(nsContentUtils::DOMDumpLog(), LogLevel::Debug, ("%s", str.get()));
-+ #ifdef ANDROID
-+   __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", str.get());
-+ #endif
+diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp
+--- a/dom/console/Console.cpp
++++ b/dom/console/Console.cpp
+@@ -2664,18 +2664,17 @@ Console::MaybeExecuteDumpFunctionForTrac
+   message.AppendLiteral("\n");
+   ExecuteDumpFunction(message);
+ }
+ 
+ void
+ Console::ExecuteDumpFunction(const nsAString& aMessage)
+ {
+   if (mDumpFunction) {
+-    IgnoredErrorResult rv;
+-    mDumpFunction->Call(aMessage, rv);
++    mDumpFunction->Call(aMessage);
+     return;
+   }
+ 
+   NS_ConvertUTF16toUTF8 str(aMessage);
+   MOZ_LOG(nsContentUtils::DOMDumpLog(), LogLevel::Debug, ("%s", str.get()));
+ #ifdef ANDROID
+   __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", str.get());
+ #endif
 diff --git a/dom/events/DOMEventTargetHelper.cpp b/dom/events/DOMEventTargetHelper.cpp
 --- a/dom/events/DOMEventTargetHelper.cpp
 +++ b/dom/events/DOMEventTargetHelper.cpp
@@ -445,7 +441,7 @@ diff --git a/dom/html/HTMLImageElement.cpp b/dom/html/HTMLImageElement.cpp
 diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
 --- a/dom/html/HTMLInputElement.cpp
 +++ b/dom/html/HTMLInputElement.cpp
-@@ -757,18 +757,17 @@ nsColorPickerShownCallback::UpdateIntern
+@@ -743,18 +743,17 @@ nsColorPickerShownCallback::UpdateIntern
  
    nsAutoString oldValue;
    if (aTrustedUpdate) {
@@ -465,7 +461,7 @@ diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
        valueChanged = true;
      }
    }
-@@ -1916,25 +1915,23 @@ HTMLInputElement::GetList(nsIDOMHTMLElem
+@@ -1902,25 +1901,23 @@ HTMLInputElement::GetList(nsIDOMHTMLElem
  }
  
  void
@@ -493,7 +489,7 @@ diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
    if (!IsDateTimeInputType(mType)) {
      return Nullable<Date>();
    }
-@@ -6698,18 +6695,17 @@ HTMLInputElement::RestoreState(nsPresSta
+@@ -6699,18 +6696,17 @@ HTMLInputElement::RestoreState(nsPresSta
          // before the type change.)
          SetValueInternal(inputState->GetValue(),
                           nsTextEditorState::eSetValue_Notify);
@@ -723,7 +719,7 @@ diff --git a/dom/html/ImageDocument.cpp b/dom/html/ImageDocument.cpp
 diff --git a/dom/html/nsTextEditorState.cpp b/dom/html/nsTextEditorState.cpp
 --- a/dom/html/nsTextEditorState.cpp
 +++ b/dom/html/nsTextEditorState.cpp
-@@ -2126,22 +2126,20 @@ nsTextEditorState::UnbindFromFrame(nsTex
+@@ -2036,22 +2036,20 @@ nsTextEditorState::UnbindFromFrame(nsTex
    // Save our selection state if needed.
    // Note that GetSelectionRange will attempt to work with our selection
    // controller, so we should make sure we do it before we start doing things
@@ -734,10 +730,9 @@ diff --git a/dom/html/nsTextEditorState.cpp b/dom/html/nsTextEditorState.cpp
      uint32_t start = 0, end = 0;
 -    IgnoredErrorResult rangeRv;
 -    GetSelectionRange(&start, &end, rangeRv);
--
--    IgnoredErrorResult dirRv;
 +    GetSelectionRange(&start, &end, IgnoreErrors());
-+
+ 
+-    IgnoredErrorResult dirRv;
      nsITextControlFrame::SelectionDirection direction =
 -      GetSelectionDirection(dirRv);
 +      GetSelectionDirection(IgnoreErrors());
@@ -869,7 +864,7 @@ new file mode 100644
 diff --git a/dom/svg/SVGAnimationElement.cpp b/dom/svg/SVGAnimationElement.cpp
 --- a/dom/svg/SVGAnimationElement.cpp
 +++ b/dom/svg/SVGAnimationElement.cpp
-@@ -391,18 +391,17 @@ SVGAnimationElement::ActivateByHyperlink
+@@ -381,18 +381,17 @@ SVGAnimationElement::ActivateByHyperlink
        AnimationNeedsResample();
        // As with SVGSVGElement::SetCurrentTime, we need to trigger
        // a synchronous sample now.
@@ -1050,7 +1045,7 @@ new file mode 100644
 diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
 --- a/dom/workers/ScriptLoader.cpp
 +++ b/dom/workers/ScriptLoader.cpp
-@@ -1554,18 +1554,17 @@ CacheCreator::DeleteCache()
+@@ -1563,18 +1563,17 @@ CacheCreator::DeleteCache()
  {
    AssertIsOnMainThread();
  
@@ -1070,7 +1065,7 @@ diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
    FailLoaders(NS_ERROR_FAILURE);
  }
  
-@@ -1686,23 +1685,22 @@ CacheScriptLoader::ResolvedCallback(JSCo
+@@ -1695,23 +1694,22 @@ CacheScriptLoader::ResolvedCallback(JSCo
    rv = UNWRAP_OBJECT(Response, &obj, response);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      Fail(rv);
@@ -1148,7 +1143,7 @@ diff --git a/dom/xbl/nsXBLPrototypeHandler.cpp b/dom/xbl/nsXBLPrototypeHandler.c
 diff --git a/dom/xul/nsXULElement.cpp b/dom/xul/nsXULElement.cpp
 --- a/dom/xul/nsXULElement.cpp
 +++ b/dom/xul/nsXULElement.cpp
-@@ -917,18 +917,17 @@ nsXULElement::RemoveChildAt(uint32_t aIn
+@@ -894,18 +894,17 @@ nsXULElement::RemoveChildAt(uint32_t aIn
            }
          }
  

+ 30 - 0
mozilla-release/patches/1440816-1-60a1.patch

@@ -0,0 +1,30 @@
+# HG changeset patch
+# User Kris Maglione <maglione.k@gmail.com>
+# Date 1519435232 28800
+# Node ID 4e681b986b5cdd36dbb8b50c232b8b5d4db8e4f3
+# Parent  5999aa753c8a0f05d4a3aadef71904495f3053a5
+Bug 1440816: Part 1 - Set readPrincipals callback on JS context. r=fitzgen
+
+MozReview-Commit-ID: L9SQ5tiHkl5
+
+diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp
+--- a/js/xpconnect/src/XPCJSRuntime.cpp
++++ b/js/xpconnect/src/XPCJSRuntime.cpp
+@@ -2899,16 +2899,17 @@ XPCJSRuntime::Initialize(JSContext* cx)
+     mPrevGCSliceCallback = JS::SetGCSliceCallback(cx, GCSliceCallback);
+     mPrevDoCycleCollectionCallback = JS::SetDoCycleCollectionCallback(cx,
+             DoCycleCollectionCallback);
+     JS_AddFinalizeCallback(cx, FinalizeCallback, nullptr);
+     JS_AddWeakPointerZonesCallback(cx, WeakPointerZonesCallback, this);
+     JS_AddWeakPointerCompartmentCallback(cx, WeakPointerCompartmentCallback, this);
+     JS_SetWrapObjectCallbacks(cx, &WrapObjectCallbacks);
+     js::SetPreserveWrapperCallback(cx, PreserveWrapper);
++    JS_InitReadPrincipalsCallback(cx, nsJSPrincipals::ReadPrincipals);
+     JS_SetAccumulateTelemetryCallback(cx, AccumulateTelemetryCallback);
+     JS_SetSetUseCounterCallback(cx, SetUseCounterCallback);
+     js::SetWindowProxyClass(cx, &OuterWindowProxyClass);
+     js::SetXrayJitInfo(&gXrayJitInfo);
+     JS::SetProcessLargeAllocationFailureCallback(OnLargeAllocationFailureCallback);
+ 
+     // The JS engine needs to keep the source code around in order to implement
+     // Function.prototype.toSource(). It'd be nice to not have to do this for

+ 250 - 0
mozilla-release/patches/1440816-2-60a1.patch

@@ -0,0 +1,250 @@
+# HG changeset patch
+# User Kris Maglione <maglione.k@gmail.com>
+# Date 1519435309 28800
+# Node ID b93a9c630a0c9ce75b5fc1a0ab91f3a9adbbab87
+# Parent  ecc9a4c889cf8d5f0c289d09eaa4633f778408e0
+Bug 1440816: Part 2 - Clone stacks when sending console messages to the parent process. r=baku
+
+MozReview-Commit-ID: FqK2eZ3JoB2
+
+diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp
+--- a/dom/ipc/ContentChild.cpp
++++ b/dom/ipc/ContentChild.cpp
+@@ -441,16 +441,48 @@ ConsoleListener::Observe(nsIConsoleMessa
+     NS_ENSURE_SUCCESS(rv, rv);
+     rv = scriptError->GetLineNumber(&lineNum);
+     NS_ENSURE_SUCCESS(rv, rv);
+     rv = scriptError->GetColumnNumber(&colNum);
+     NS_ENSURE_SUCCESS(rv, rv);
+     rv = scriptError->GetFlags(&flags);
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
++    {
++      AutoJSAPI jsapi;
++      jsapi.Init();
++      JSContext* cx = jsapi.cx();
++
++      JS::RootedValue stack(cx);
++      rv = scriptError->GetStack(&stack);
++      NS_ENSURE_SUCCESS(rv, rv);
++
++      if (stack.isObject()) {
++        JSAutoCompartment ac(cx, &stack.toObject());
++
++        StructuredCloneData data;
++        ErrorResult err;
++        data.Write(cx, stack, err);
++        if (err.Failed()) {
++          return err.StealNSResult();
++        }
++
++        ClonedMessageData cloned;
++        if (!data.BuildClonedMessageDataForChild(mChild, cloned)) {
++          return NS_ERROR_FAILURE;
++        }
++
++        mChild->SendScriptErrorWithStack(msg, sourceName, sourceLine,
++                                         lineNum, colNum, flags, category,
++                                         cloned);
++        return NS_OK;
++      }
++    }
++
++
+     mChild->SendScriptError(msg, sourceName, sourceLine,
+                             lineNum, colNum, flags, category);
+     return NS_OK;
+   }
+ 
+   nsString msg;
+   nsresult rv = aMessage->GetMessageMoz(getter_Copies(msg));
+   NS_ENSURE_SUCCESS(rv, rv);
+diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp
+--- a/dom/ipc/ContentParent.cpp
++++ b/dom/ipc/ContentParent.cpp
+@@ -150,16 +150,17 @@
+ #include "nsIWindowWatcher.h"
+ #include "nsPIWindowWatcher.h"
+ #include "nsThread.h"
+ #include "nsWindowWatcher.h"
+ #include "nsIXULRuntime.h"
+ #include "mozilla/dom/nsMixedContentBlocker.h"
+ #include "nsMemoryInfoDumper.h"
+ #include "nsMemoryReporterManager.h"
++#include "nsScriptError.h"
+ #include "nsServiceManagerUtils.h"
+ #include "nsStyleSheetService.h"
+ #include "nsThreadUtils.h"
+ #include "nsToolkitCompsCID.h"
+ #include "nsWidgetsCID.h"
+ #include "PreallocatedProcessManager.h"
+ #include "ProcessPriorityManager.h"
+ #include "SandboxHal.h"
+@@ -3774,24 +3775,80 @@ mozilla::ipc::IPCResult
+ ContentParent::RecvScriptError(const nsString& aMessage,
+                                const nsString& aSourceName,
+                                const nsString& aSourceLine,
+                                const uint32_t& aLineNumber,
+                                const uint32_t& aColNumber,
+                                const uint32_t& aFlags,
+                                const nsCString& aCategory)
+ {
++  return RecvScriptErrorInternal(aMessage, aSourceName, aSourceLine,
++                                 aLineNumber, aColNumber, aFlags,
++                                 aCategory);
++}
++
++mozilla::ipc::IPCResult
++ContentParent::RecvScriptErrorWithStack(const nsString& aMessage,
++                                        const nsString& aSourceName,
++                                        const nsString& aSourceLine,
++                                        const uint32_t& aLineNumber,
++                                        const uint32_t& aColNumber,
++                                        const uint32_t& aFlags,
++                                        const nsCString& aCategory,
++                                        const ClonedMessageData& aFrame)
++{
++  return RecvScriptErrorInternal(aMessage, aSourceName, aSourceLine,
++                                 aLineNumber, aColNumber, aFlags,
++                                 aCategory, &aFrame);
++}
++
++mozilla::ipc::IPCResult
++ContentParent::RecvScriptErrorInternal(const nsString& aMessage,
++                                       const nsString& aSourceName,
++                                       const nsString& aSourceLine,
++                                       const uint32_t& aLineNumber,
++                                       const uint32_t& aColNumber,
++                                       const uint32_t& aFlags,
++                                       const nsCString& aCategory,
++                                       const ClonedMessageData* aStack)
++{
+   RefPtr<nsConsoleService> consoleService = GetConsoleService();
+   if (!consoleService) {
+     return IPC_OK();
+   }
+ 
+-  nsCOMPtr<nsIScriptError> msg(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
+-  nsresult rv = msg->Init(aMessage, aSourceName, aSourceLine,
+-                          aLineNumber, aColNumber, aFlags, aCategory.get());
++  nsCOMPtr<nsIScriptError> msg;
++
++  if (aStack) {
++    StructuredCloneData data;
++    UnpackClonedMessageDataForParent(*aStack, data);
++
++    AutoJSAPI jsapi;
++    if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
++      MOZ_CRASH();
++    }
++    JSContext* cx = jsapi.cx();
++
++    JS::RootedValue stack(cx);
++    ErrorResult rv;
++    data.Read(cx, &stack, rv);
++    if (rv.Failed() || !stack.isObject()) {
++      rv.SuppressException();
++      return IPC_OK();
++    }
++
++    JS::RootedObject stackObj(cx, &stack.toObject());
++    msg = new nsScriptErrorWithStack(stackObj);
++  } else {
++    msg = new nsScriptError();
++  }
++
++  nsresult rv = msg->InitWithWindowID(aMessage, aSourceName, aSourceLine,
++                                      aLineNumber, aColNumber, aFlags,
++                                      aCategory, 0);
+   if (NS_FAILED(rv))
+     return IPC_OK();
+ 
+   consoleService->LogMessageWithMode(msg, nsConsoleService::SuppressLog);
+   return IPC_OK();
+ }
+ 
+ mozilla::ipc::IPCResult
+diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h
+--- a/dom/ipc/ContentParent.h
++++ b/dom/ipc/ContentParent.h
+@@ -1018,16 +1018,36 @@ private:
+   virtual mozilla::ipc::IPCResult RecvScriptError(const nsString& aMessage,
+                                                   const nsString& aSourceName,
+                                                   const nsString& aSourceLine,
+                                                   const uint32_t& aLineNumber,
+                                                   const uint32_t& aColNumber,
+                                                   const uint32_t& aFlags,
+                                                   const nsCString& aCategory) override;
+ 
++  virtual mozilla::ipc::IPCResult RecvScriptErrorWithStack(const nsString& aMessage,
++                                                           const nsString& aSourceName,
++                                                           const nsString& aSourceLine,
++                                                           const uint32_t& aLineNumber,
++                                                           const uint32_t& aColNumber,
++                                                           const uint32_t& aFlags,
++                                                           const nsCString& aCategory,
++                                                           const ClonedMessageData& aStack) override;
++
++private:
++  mozilla::ipc::IPCResult RecvScriptErrorInternal(const nsString& aMessage,
++                                                  const nsString& aSourceName,
++                                                  const nsString& aSourceLine,
++                                                  const uint32_t& aLineNumber,
++                                                  const uint32_t& aColNumber,
++                                                  const uint32_t& aFlags,
++                                                  const nsCString& aCategory,
++                                                  const ClonedMessageData* aStack = nullptr);
++
++public:
+   virtual mozilla::ipc::IPCResult RecvPrivateDocShellsExist(const bool& aExist) override;
+ 
+   virtual mozilla::ipc::IPCResult RecvFirstIdle() override;
+ 
+   virtual mozilla::ipc::IPCResult RecvDeviceReset() override;
+ 
+   virtual mozilla::ipc::IPCResult RecvKeywordToURI(const nsCString& aKeyword,
+                                                    nsString* aProviderName,
+diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl
+--- a/dom/ipc/PContent.ipdl
++++ b/dom/ipc/PContent.ipdl
+@@ -758,16 +758,19 @@ parent:
+     async AddGeolocationListener(Principal principal, bool highAccuracy);
+     async RemoveGeolocationListener();
+     async SetGeolocationHigherAccuracy(bool enable);
+ 
+     async ConsoleMessage(nsString message);
+     async ScriptError(nsString message, nsString sourceName, nsString sourceLine,
+                       uint32_t lineNumber, uint32_t colNumber, uint32_t flags,
+                       nsCString category);
++    async ScriptErrorWithStack(nsString message, nsString sourceName, nsString sourceLine,
++                               uint32_t lineNumber, uint32_t colNumber, uint32_t flags,
++                               nsCString category, ClonedMessageData stack);
+ 
+     // Places the items within dataTransfer on the clipboard.
+     async SetClipboard(IPCDataTransfer aDataTransfer,
+                        bool aIsPrivateData,
+                        Principal aRequestingPrincipal,
+                        int32_t aWhichClipboard);
+ 
+     // Given a list of supported types, returns the clipboard data for the
+diff --git a/dom/ipc/moz.build b/dom/ipc/moz.build
+--- a/dom/ipc/moz.build
++++ b/dom/ipc/moz.build
+@@ -115,16 +115,17 @@ if CONFIG['MOZ_CONTENT_SANDBOX'] and CON
+         'mozsandbox',
+     ]
+ 
+ LOCAL_INCLUDES += [
+     '/caps',
+     '/chrome',
+     '/docshell/base',
+     '/dom/base',
++    '/dom/bindings',
+     '/dom/events',
+     '/dom/filesystem',
+     '/dom/geolocation',
+     '/dom/media/webspeech/synth/ipc',
+     '/dom/security',
+     '/dom/workers',
+     '/extensions/cookie',
+     '/extensions/spellcheck/src',

+ 1326 - 0
mozilla-release/patches/1443079-61a1.patch

@@ -0,0 +1,1326 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1520919638 -3600
+# Node ID 47a89fa7cfd2f1628fa08dc69687eddfaf7f94bb
+# Parent  80bf73c0191e02d275d56e92ff7e67fce3cb6605
+Bug 1443079 - nsScriptError.isFromPrivateWindow must match the correct value also in e10s mode, r=smaug
+
+diff --git a/chrome/nsChromeRegistry.cpp b/chrome/nsChromeRegistry.cpp
+--- a/chrome/nsChromeRegistry.cpp
++++ b/chrome/nsChromeRegistry.cpp
+@@ -85,17 +85,18 @@ nsChromeRegistry::LogMessageWithContext(
+ 
+   nsCString spec;
+   if (aURL)
+     aURL->GetSpec(spec);
+ 
+   rv = error->Init(NS_ConvertUTF8toUTF16(formatted.get()),
+                    NS_ConvertUTF8toUTF16(spec),
+                    EmptyString(),
+-                   aLineNumber, 0, flags, "chrome registration");
++                   aLineNumber, 0, flags, "chrome registration",
++                   false /* from private window */);
+ 
+   if (NS_FAILED(rv))
+     return;
+ 
+   console->LogMessage(error);
+ }
+ 
+ nsChromeRegistry::~nsChromeRegistry()
+diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
+--- a/dom/base/nsContentUtils.cpp
++++ b/dom/base/nsContentUtils.cpp
+@@ -4182,27 +4182,29 @@ nsresult nsContentUtils::FormatLocalized
+   }
+   return FormatLocalizedString(aFile, aKey, params.get(), paramsLength,
+                                aResult);
+ }
+ 
+ 
+ /* static */ void
+ nsContentUtils::LogSimpleConsoleError(const nsAString& aErrorText,
+-                                      const char * classification)
++                                      const char * classification,
++                                      bool aFromPrivateWindow)
+ {
+   nsCOMPtr<nsIScriptError> scriptError =
+     do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
+   if (scriptError) {
+     nsCOMPtr<nsIConsoleService> console =
+       do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+     if (console && NS_SUCCEEDED(scriptError->Init(aErrorText, EmptyString(),
+                                                   EmptyString(), 0, 0,
+                                                   nsIScriptError::errorFlag,
+-                                                  classification))) {
++                                                  classification,
++                                                  aFromPrivateWindow))) {
+       console->LogMessage(scriptError);
+     }
+   }
+ }
+ 
+ /* static */ nsresult
+ nsContentUtils::ReportToConsole(uint32_t aErrorFlags,
+                                 const nsACString& aCategory,
+@@ -5864,17 +5866,18 @@ nsContentUtils::WarnScriptWasIgnored(nsI
+     nsCOMPtr<nsIURI> uri = aDocument->GetDocumentURI();
+     if (uri) {
+       msg.Append(NS_ConvertUTF8toUTF16(uri->GetSpecOrDefault()));
+       msg.AppendLiteral(" : ");
+     }
+   }
+   msg.AppendLiteral("Unable to run script because scripts are blocked internally.");
+ 
+-  LogSimpleConsoleError(msg, "DOM");
++  LogSimpleConsoleError(msg, "DOM",
++                        !!aDocument->NodePrincipal()->OriginAttributesRef().mPrivateBrowsingId);
+ }
+ 
+ /* static */
+ void
+ nsContentUtils::AddScriptRunner(already_AddRefed<nsIRunnable> aRunnable)
+ {
+   nsCOMPtr<nsIRunnable> runnable = aRunnable;
+   if (!runnable) {
+diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
+--- a/dom/base/nsContentUtils.h
++++ b/dom/base/nsContentUtils.h
+@@ -990,17 +990,18 @@ public:
+   }
+ 
+   /**
+    * Report simple error message to the browser console
+    *   @param aErrorText the error message
+    *   @param classification Name of the module reporting error
+    */
+   static void LogSimpleConsoleError(const nsAString& aErrorText,
+-                                    const char * classification);
++                                    const char * classification,
++                                    bool aFromPrivateWindow);
+ 
+   /**
+    * Report a non-localized error message to the error console.
+    *   @param aErrorText the error message
+    *   @param aErrorFlags See nsIScriptError.
+    *   @param aCategory Name of module reporting error.
+    *   @param aDocument Reference to the document which triggered the message.
+    *   @param [aURI=nullptr] (Optional) URI of resource containing error.
+diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp
+--- a/dom/base/nsFrameMessageManager.cpp
++++ b/dom/base/nsFrameMessageManager.cpp
+@@ -509,17 +509,18 @@ GetParamsForMessage(JSContext* aCx,
+   nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
+   if (console) {
+     nsAutoString filename;
+     uint32_t lineno = 0, column = 0;
+     nsJSUtils::GetCallingLocation(aCx, filename, &lineno, &column);
+     nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
+     error->Init(NS_LITERAL_STRING("Sending message that cannot be cloned. Are you trying to send an XPCOM object?"),
+                 filename, EmptyString(), lineno, column,
+-                nsIScriptError::warningFlag, "chrome javascript");
++                nsIScriptError::warningFlag, "chrome javascript",
++                false /* from private window */);
+     console->LogMessage(error);
+   }
+ 
+   // Not clonable, try JSON
+   //XXX This is ugly but currently structured cloning doesn't handle
+   //    properly cases when interface is implemented in JS and used
+   //    as a dictionary.
+   nsAutoString json;
+@@ -1106,17 +1107,18 @@ nsFrameMessageManager::ReceiveMessage(ns
+           if (NS_WARN_IF(rv.Failed())) {
+             aRetVal->RemoveElementAt(aRetVal->Length() - 1);
+             nsString msg = aMessage + NS_LITERAL_STRING(": message reply cannot be cloned. Are you trying to send an XPCOM object?");
+ 
+             nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
+             if (console) {
+               nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
+               error->Init(msg, EmptyString(), EmptyString(),
+-                          0, 0, nsIScriptError::warningFlag, "chrome javascript");
++                          0, 0, nsIScriptError::warningFlag, "chrome javascript",
++                          false /* from private window */);
+               console->LogMessage(error);
+             }
+ 
+             JS_ClearPendingException(cx);
+             continue;
+           }
+         }
+       }
+diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
+--- a/dom/base/nsGlobalWindow.cpp
++++ b/dom/base/nsGlobalWindow.cpp
+@@ -9127,17 +9127,18 @@ nsGlobalWindow::PostMessageMozOuter(JSCo
+         }
+ 
+         nsContentUtils::LogSimpleConsoleError(
+           NS_ConvertUTF8toUTF16(nsPrintfCString(
+             R"(Attempting to post a message to window with url "%s" and )"
+             R"(origin "%s" from a system principal scope with mismatched )"
+             R"(origin "%s".)",
+             targetURL.get(), targetOrigin.get(), sourceOrigin.get())),
+-          "DOM");
++          "DOM",
++          !!principal->PrivateBrowsingId());
+ 
+         attrs = principal->OriginAttributesRef();
+       }
+     }
+ 
+     // Create a nsIPrincipal inheriting the app/browser attributes from the
+     // caller.
+     providedPrincipal = BasePrincipal::CreateCodebasePrincipal(originURI, attrs);
+diff --git a/dom/bindings/nsIScriptError.idl b/dom/bindings/nsIScriptError.idl
+--- a/dom/bindings/nsIScriptError.idl
++++ b/dom/bindings/nsIScriptError.idl
+@@ -90,17 +90,18 @@ interface nsIScriptError : nsIConsoleMes
+     readonly attribute nsIArray notes;
+ 
+     void init(in AString message,
+               in AString sourceName,
+               in AString sourceLine,
+               in uint32_t lineNumber,
+               in uint32_t columnNumber,
+               in uint32_t flags,
+-              in string category);
++              in string category,
++              [optional] in bool fromPrivateWindow);
+ 
+     /* This should be called instead of nsIScriptError.init to
+      * initialize with a window id.  The window id should be for the
+      * inner window associated with this error.
+      *
+      * This function will check whether sourceName is a uri and sanitize it if
+      * needed. If you know the source name is sanitized already, use
+      * initWithSanitizedSource.
+diff --git a/dom/bindings/nsScriptError.cpp b/dom/bindings/nsScriptError.cpp
+--- a/dom/bindings/nsScriptError.cpp
++++ b/dom/bindings/nsScriptError.cpp
+@@ -176,32 +176,16 @@ nsScriptErrorBase::GetErrorMessageName(n
+ }
+ 
+ NS_IMETHODIMP
+ nsScriptErrorBase::SetErrorMessageName(const nsAString& aErrorMessageName) {
+     mMessageName = aErrorMessageName;
+     return NS_OK;
+ }
+ 
+-NS_IMETHODIMP
+-nsScriptErrorBase::Init(const nsAString& message,
+-                        const nsAString& sourceName,
+-                        const nsAString& sourceLine,
+-                        uint32_t lineNumber,
+-                        uint32_t columnNumber,
+-                        uint32_t flags,
+-                        const char* category)
+-{
+-    return InitWithWindowID(message, sourceName, sourceLine, lineNumber,
+-                            columnNumber, flags,
+-                            category ? nsDependentCString(category)
+-                                     : EmptyCString(),
+-                            0);
+-}
+-
+ static void
+ AssignSourceNameHelper(nsString& aSourceNameDest, const nsAString& aSourceNameSrc)
+ {
+     if (aSourceNameSrc.IsEmpty())
+         return;
+ 
+     aSourceNameDest.Assign(aSourceNameSrc);
+ 
+@@ -222,16 +206,36 @@ AssignSourceNameHelper(nsIURI* aSourceUR
+         return;
+ 
+     if (NS_FAILED(NS_GetSanitizedURIStringFromURI(aSourceURI,
+                                                   aSourceNameDest))) {
+         aSourceNameDest.AssignLiteral("[nsIURI::GetSpec failed]");
+     }
+ }
+ 
++NS_IMETHODIMP
++nsScriptErrorBase::Init(const nsAString& message,
++                        const nsAString& sourceName,
++                        const nsAString& sourceLine,
++                        uint32_t lineNumber,
++                        uint32_t columnNumber,
++                        uint32_t flags,
++                        const char* category,
++                        bool fromPrivateWindow)
++{
++    InitializationHelper(message, sourceLine, lineNumber, columnNumber, flags,
++                         category ? nsDependentCString(category)
++                                  : EmptyCString(),
++                         0 /* inner Window ID */);
++    AssignSourceNameHelper(mSourceName, sourceName);
++
++    mIsFromPrivateWindow = fromPrivateWindow;
++    return NS_OK;
++}
++
+ void
+ nsScriptErrorBase::InitializationHelper(const nsAString& message,
+                                         const nsAString& sourceLine,
+                                         uint32_t lineNumber,
+                                         uint32_t columnNumber,
+                                         uint32_t flags,
+                                         const nsACString& category,
+                                         uint64_t aInnerWindowID)
+diff --git a/dom/bindings/nsScriptError.h b/dom/bindings/nsScriptError.h
+--- a/dom/bindings/nsScriptError.h
++++ b/dom/bindings/nsScriptError.h
+@@ -91,24 +91,16 @@ private:
+ 
+ class nsScriptErrorWithStack : public nsScriptErrorBase {
+ public:
+   explicit nsScriptErrorWithStack(JS::HandleObject);
+ 
+   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsScriptErrorWithStack)
+ 
+-  NS_IMETHOD Init(const nsAString& message,
+-                  const nsAString& sourceName,
+-                  const nsAString& sourceLine,
+-                  uint32_t lineNumber,
+-                  uint32_t columnNumber,
+-                  uint32_t flags,
+-                  const char* category) override;
+-
+   NS_IMETHOD GetStack(JS::MutableHandleValue) override;
+   NS_IMETHOD ToString(nsACString& aResult) override;
+ 
+ private:
+   virtual ~nsScriptErrorWithStack();
+   // Complete stackframe where the error happened.
+   // Must be SavedFrame object.
+   JS::Heap<JSObject*>  mStack;
+diff --git a/dom/bindings/nsScriptErrorWithStack.cpp b/dom/bindings/nsScriptErrorWithStack.cpp
+--- a/dom/bindings/nsScriptErrorWithStack.cpp
++++ b/dom/bindings/nsScriptErrorWithStack.cpp
+@@ -69,28 +69,16 @@ nsScriptErrorWithStack::nsScriptErrorWit
+     mozilla::HoldJSObjects(this);
+ }
+ 
+ nsScriptErrorWithStack::~nsScriptErrorWithStack() {
+     mozilla::DropJSObjects(this);
+ }
+ 
+ NS_IMETHODIMP
+-nsScriptErrorWithStack::Init(const nsAString& message,
+-                             const nsAString& sourceName,
+-                             const nsAString& sourceLine,
+-                             uint32_t lineNumber,
+-                             uint32_t columnNumber,
+-                             uint32_t flags,
+-                             const char* category)
+-{
+-  MOZ_CRASH("nsScriptErrorWithStack requires to be initialized with a document, by using InitWithWindowID");
+-}
+-
+-NS_IMETHODIMP
+ nsScriptErrorWithStack::GetStack(JS::MutableHandleValue aStack) {
+     aStack.setObjectOrNull(mStack);
+     return NS_OK;
+ }
+ 
+ NS_IMETHODIMP
+ nsScriptErrorWithStack::ToString(nsACString& /*UTF8*/ aResult)
+ {
+diff --git a/dom/html/HTMLFormElement.cpp b/dom/html/HTMLFormElement.cpp
+--- a/dom/html/HTMLFormElement.cpp
++++ b/dom/html/HTMLFormElement.cpp
+@@ -1736,17 +1736,18 @@ HTMLFormElement::GetActionURL(nsIURI** a
+     const char16_t* params[] = { reportSpec.get(), reportScheme.get() };
+     CSP_LogLocalizedStr("upgradeInsecureRequest",
+                         params, ArrayLength(params),
+                         EmptyString(), // aSourceFile
+                         EmptyString(), // aScriptSample
+                         0, // aLineNumber
+                         0, // aColumnNumber
+                         nsIScriptError::warningFlag, "CSP",
+-                        document->InnerWindowID());
++                        document->InnerWindowID(),
++                        !!document->NodePrincipal()->OriginAttributesRef().mPrivateBrowsingId);
+   }
+ 
+   //
+   // Assign to the output
+   //
+   actionURL.forget(aActionURL);
+ 
+   return rv;
+diff --git a/dom/indexedDB/ReportInternalError.cpp b/dom/indexedDB/ReportInternalError.cpp
+--- a/dom/indexedDB/ReportInternalError.cpp
++++ b/dom/indexedDB/ReportInternalError.cpp
+@@ -23,14 +23,14 @@ ReportInternalError(const char* aFile, u
+     if (*p == '/' && *(p + 1)) {
+       aFile = p + 1;
+     }
+   }
+ 
+   nsContentUtils::LogSimpleConsoleError(
+     NS_ConvertUTF8toUTF16(nsPrintfCString(
+                           "IndexedDB %s: %s:%" PRIu32, aStr, aFile, aLine)),
+-    "indexedDB");
++    "indexedDB", false /* no IDB in private window */);
+ }
+ 
+ } // namespace indexedDB
+ } // namespace dom
+ } // namespace mozilla
+diff --git a/dom/indexedDB/ScriptErrorHelper.cpp b/dom/indexedDB/ScriptErrorHelper.cpp
+--- a/dom/indexedDB/ScriptErrorHelper.cpp
++++ b/dom/indexedDB/ScriptErrorHelper.cpp
+@@ -138,17 +138,18 @@ public:
+     } else {
+       MOZ_ALWAYS_SUCCEEDS(
+         scriptError->Init(aMessage,
+                           aFilename,
+                           /* aSourceLine */ EmptyString(),
+                           aLineNumber,
+                           aColumnNumber,
+                           aSeverityFlag,
+-                          category.get()));
++                          category.get(),
++                          /* IDB doesn't run on Private browsing mode */ false));
+     }
+ 
+     MOZ_ALWAYS_SUCCEEDS(consoleService->LogMessage(scriptError));
+   }
+ 
+   NS_IMETHOD
+   Run() override
+   {
+diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp
+--- a/dom/ipc/ContentChild.cpp
++++ b/dom/ipc/ContentChild.cpp
+@@ -421,16 +421,17 @@ ConsoleListener::Observe(nsIConsoleMessa
+     return NS_OK;
+   }
+ 
+   nsCOMPtr<nsIScriptError> scriptError = do_QueryInterface(aMessage);
+   if (scriptError) {
+     nsAutoString msg, sourceName, sourceLine;
+     nsCString category;
+     uint32_t lineNum, colNum, flags;
++    bool fromPrivateWindow;
+ 
+     nsresult rv = scriptError->GetErrorMessage(msg);
+     NS_ENSURE_SUCCESS(rv, rv);
+     TruncateString(msg);
+     rv = scriptError->GetSourceName(sourceName);
+     NS_ENSURE_SUCCESS(rv, rv);
+     TruncateString(sourceName);
+     rv = scriptError->GetSourceLine(sourceLine);
+@@ -440,16 +441,18 @@ ConsoleListener::Observe(nsIConsoleMessa
+     rv = scriptError->GetCategory(getter_Copies(category));
+     NS_ENSURE_SUCCESS(rv, rv);
+     rv = scriptError->GetLineNumber(&lineNum);
+     NS_ENSURE_SUCCESS(rv, rv);
+     rv = scriptError->GetColumnNumber(&colNum);
+     NS_ENSURE_SUCCESS(rv, rv);
+     rv = scriptError->GetFlags(&flags);
+     NS_ENSURE_SUCCESS(rv, rv);
++    rv = scriptError->GetIsFromPrivateWindow(&fromPrivateWindow);
++    NS_ENSURE_SUCCESS(rv, rv);
+ 
+     {
+       AutoJSAPI jsapi;
+       jsapi.Init();
+       JSContext* cx = jsapi.cx();
+ 
+       JS::RootedValue stack(cx);
+       rv = scriptError->GetStack(&stack);
+@@ -467,24 +470,25 @@ ConsoleListener::Observe(nsIConsoleMessa
+ 
+         ClonedMessageData cloned;
+         if (!data.BuildClonedMessageDataForChild(mChild, cloned)) {
+           return NS_ERROR_FAILURE;
+         }
+ 
+         mChild->SendScriptErrorWithStack(msg, sourceName, sourceLine,
+                                          lineNum, colNum, flags, category,
+-                                         cloned);
++                                         fromPrivateWindow, cloned);
+         return NS_OK;
+       }
+     }
+ 
+ 
+     mChild->SendScriptError(msg, sourceName, sourceLine,
+-                            lineNum, colNum, flags, category);
++                            lineNum, colNum, flags, category,
++                            fromPrivateWindow);
+     return NS_OK;
+   }
+ 
+   nsString msg;
+   nsresult rv = aMessage->GetMessageMoz(getter_Copies(msg));
+   NS_ENSURE_SUCCESS(rv, rv);
+   mChild->SendConsoleMessage(msg);
+   return NS_OK;
+diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp
+--- a/dom/ipc/ContentParent.cpp
++++ b/dom/ipc/ContentParent.cpp
+@@ -3773,46 +3773,49 @@ ContentParent::RecvConsoleMessage(const 
+ 
+ mozilla::ipc::IPCResult
+ ContentParent::RecvScriptError(const nsString& aMessage,
+                                const nsString& aSourceName,
+                                const nsString& aSourceLine,
+                                const uint32_t& aLineNumber,
+                                const uint32_t& aColNumber,
+                                const uint32_t& aFlags,
+-                               const nsCString& aCategory)
++                               const nsCString& aCategory,
++                               const bool& aFromPrivateWindow)
+ {
+   return RecvScriptErrorInternal(aMessage, aSourceName, aSourceLine,
+                                  aLineNumber, aColNumber, aFlags,
+-                                 aCategory);
++                                 aCategory, aFromPrivateWindow);
+ }
+ 
+ mozilla::ipc::IPCResult
+ ContentParent::RecvScriptErrorWithStack(const nsString& aMessage,
+                                         const nsString& aSourceName,
+                                         const nsString& aSourceLine,
+                                         const uint32_t& aLineNumber,
+                                         const uint32_t& aColNumber,
+                                         const uint32_t& aFlags,
+                                         const nsCString& aCategory,
++                                        const bool& aFromPrivateWindow,
+                                         const ClonedMessageData& aFrame)
+ {
+   return RecvScriptErrorInternal(aMessage, aSourceName, aSourceLine,
+                                  aLineNumber, aColNumber, aFlags,
+-                                 aCategory, &aFrame);
++                                 aCategory, aFromPrivateWindow, &aFrame);
+ }
+ 
+ mozilla::ipc::IPCResult
+ ContentParent::RecvScriptErrorInternal(const nsString& aMessage,
+                                        const nsString& aSourceName,
+                                        const nsString& aSourceLine,
+                                        const uint32_t& aLineNumber,
+                                        const uint32_t& aColNumber,
+                                        const uint32_t& aFlags,
+                                        const nsCString& aCategory,
++                                       const bool& aFromPrivateWindow,
+                                        const ClonedMessageData* aStack)
+ {
+   RefPtr<nsConsoleService> consoleService = GetConsoleService();
+   if (!consoleService) {
+     return IPC_OK();
+   }
+ 
+   nsCOMPtr<nsIScriptError> msg;
+@@ -3836,19 +3839,19 @@ ContentParent::RecvScriptErrorInternal(c
+     }
+ 
+     JS::RootedObject stackObj(cx, &stack.toObject());
+     msg = new nsScriptErrorWithStack(stackObj);
+   } else {
+     msg = new nsScriptError();
+   }
+ 
+-  nsresult rv = msg->InitWithWindowID(aMessage, aSourceName, aSourceLine,
+-                                      aLineNumber, aColNumber, aFlags,
+-                                      aCategory, 0);
++  nsresult rv = msg->Init(aMessage, aSourceName, aSourceLine,
++                          aLineNumber, aColNumber, aFlags,
++                          aCategory.get(), aFromPrivateWindow);
+   if (NS_FAILED(rv))
+     return IPC_OK();
+ 
+   consoleService->LogMessageWithMode(msg, nsConsoleService::SuppressLog);
+   return IPC_OK();
+ }
+ 
+ mozilla::ipc::IPCResult
+diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h
+--- a/dom/ipc/ContentParent.h
++++ b/dom/ipc/ContentParent.h
+@@ -1016,35 +1016,38 @@ private:
+   virtual mozilla::ipc::IPCResult RecvConsoleMessage(const nsString& aMessage) override;
+ 
+   virtual mozilla::ipc::IPCResult RecvScriptError(const nsString& aMessage,
+                                                   const nsString& aSourceName,
+                                                   const nsString& aSourceLine,
+                                                   const uint32_t& aLineNumber,
+                                                   const uint32_t& aColNumber,
+                                                   const uint32_t& aFlags,
+-                                                  const nsCString& aCategory) override;
++                                                  const nsCString& aCategory,
++                                                  const bool& aIsFromPrivateWindow) override;
+ 
+   virtual mozilla::ipc::IPCResult RecvScriptErrorWithStack(const nsString& aMessage,
+                                                            const nsString& aSourceName,
+                                                            const nsString& aSourceLine,
+                                                            const uint32_t& aLineNumber,
+                                                            const uint32_t& aColNumber,
+                                                            const uint32_t& aFlags,
+                                                            const nsCString& aCategory,
++                                                           const bool& aIsFromPrivateWindow,
+                                                            const ClonedMessageData& aStack) override;
+ 
+ private:
+   mozilla::ipc::IPCResult RecvScriptErrorInternal(const nsString& aMessage,
+                                                   const nsString& aSourceName,
+                                                   const nsString& aSourceLine,
+                                                   const uint32_t& aLineNumber,
+                                                   const uint32_t& aColNumber,
+                                                   const uint32_t& aFlags,
+                                                   const nsCString& aCategory,
++                                                  const bool& aIsFromPrivateWindow,
+                                                   const ClonedMessageData* aStack = nullptr);
+ 
+ public:
+   virtual mozilla::ipc::IPCResult RecvPrivateDocShellsExist(const bool& aExist) override;
+ 
+   virtual mozilla::ipc::IPCResult RecvFirstIdle() override;
+ 
+   virtual mozilla::ipc::IPCResult RecvDeviceReset() override;
+diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl
+--- a/dom/ipc/PContent.ipdl
++++ b/dom/ipc/PContent.ipdl
+@@ -757,20 +757,21 @@ parent:
+ 
+     async AddGeolocationListener(Principal principal, bool highAccuracy);
+     async RemoveGeolocationListener();
+     async SetGeolocationHigherAccuracy(bool enable);
+ 
+     async ConsoleMessage(nsString message);
+     async ScriptError(nsString message, nsString sourceName, nsString sourceLine,
+                       uint32_t lineNumber, uint32_t colNumber, uint32_t flags,
+-                      nsCString category);
++                      nsCString category, bool privateWindow);
+     async ScriptErrorWithStack(nsString message, nsString sourceName, nsString sourceLine,
+                                uint32_t lineNumber, uint32_t colNumber, uint32_t flags,
+-                               nsCString category, ClonedMessageData stack);
++                               nsCString category, bool privateWindow,
++                               ClonedMessageData stack);
+ 
+     // Places the items within dataTransfer on the clipboard.
+     async SetClipboard(IPCDataTransfer aDataTransfer,
+                        bool aIsPrivateData,
+                        Principal aRequestingPrincipal,
+                        int32_t aWhichClipboard);
+ 
+     // Given a list of supported types, returns the clipboard data for the
+diff --git a/dom/quota/ActorsParent.cpp b/dom/quota/ActorsParent.cpp
+--- a/dom/quota/ActorsParent.cpp
++++ b/dom/quota/ActorsParent.cpp
+@@ -1546,17 +1546,18 @@ ReportInternalError(const char* aFile, u
+     if (*p == '/' && *(p + 1)) {
+       aFile = p + 1;
+     }
+   }
+ 
+   nsContentUtils::LogSimpleConsoleError(
+     NS_ConvertUTF8toUTF16(nsPrintfCString(
+                           "Quota %s: %s:%" PRIu32, aStr, aFile, aLine)),
+-    "quota");
++    "quota",
++    false /* Quota Manager is not active in private browsing mode */);
+ }
+ 
+ namespace {
+ 
+ StaticRefPtr<QuotaManager> gInstance;
+ bool gCreateFailed = false;
+ StaticRefPtr<QuotaManager::CreateRunnable> gCreateRunnable;
+ mozilla::Atomic<bool> gShutdown(false);
+diff --git a/dom/security/FramingChecker.cpp b/dom/security/FramingChecker.cpp
+--- a/dom/security/FramingChecker.cpp
++++ b/dom/security/FramingChecker.cpp
+@@ -176,26 +176,28 @@ ShouldIgnoreFrameOptions(nsIChannel* aCh
+     // if CSP does not contain frame-ancestors, then there
+     // is nothing to do here.
+     return false;
+   }
+ 
+   // log warning to console that xfo is ignored because of CSP
+   nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
+   uint64_t innerWindowID = loadInfo ? loadInfo->GetInnerWindowID() : 0;
++  bool privateWindow = loadInfo ?  !!loadInfo->GetOriginAttributes().mPrivateBrowsingId : false;
+   const char16_t* params[] = { u"x-frame-options",
+                                u"frame-ancestors" };
+   CSP_LogLocalizedStr("IgnoringSrcBecauseOfDirective",
+                       params, ArrayLength(params),
+                       EmptyString(), // no sourcefile
+                       EmptyString(), // no scriptsample
+                       0,             // no linenumber
+                       0,             // no columnnumber
+                       nsIScriptError::warningFlag,
+-                      "CSP", innerWindowID);
++                      "CSP", innerWindowID,
++                      privateWindow);
+ 
+   return true;
+ }
+ 
+ // Check if X-Frame-Options permits this document to be loaded as a subdocument.
+ // This will iterate through and check any number of X-Frame-Options policies
+ // in the request (comma-separated in a header, multiple headers, etc).
+ /* static */ bool
+diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp
+--- a/dom/security/nsCSPContext.cpp
++++ b/dom/security/nsCSPContext.cpp
+@@ -788,28 +788,33 @@ struct ConsoleMsgQueueElem {
+   uint32_t      mLineNumber;
+   uint32_t      mColumnNumber;
+   uint32_t      mSeverityFlag;
+ };
+ 
+ void
+ nsCSPContext::flushConsoleMessages()
+ {
++  bool privateWindow = false;
++
+   // should flush messages even if doc is not available
+   nsCOMPtr<nsIDocument> doc = do_QueryReferent(mLoadingContext);
+   if (doc) {
+     mInnerWindowID = doc->InnerWindowID();
++    privateWindow = !!doc->NodePrincipal()->OriginAttributesRef().mPrivateBrowsingId;
+   }
++
+   mQueueUpMessages = false;
+ 
+   for (uint32_t i = 0; i < mConsoleMsgQueue.Length(); i++) {
+     ConsoleMsgQueueElem &elem = mConsoleMsgQueue[i];
+     CSP_LogMessage(elem.mMsg, elem.mSourceName, elem.mSourceLine,
+                    elem.mLineNumber, elem.mColumnNumber,
+-                   elem.mSeverityFlag, "CSP", mInnerWindowID);
++                   elem.mSeverityFlag, "CSP", mInnerWindowID,
++                   privateWindow);
+   }
+   mConsoleMsgQueue.Clear();
+ }
+ 
+ void
+ nsCSPContext::logToConsole(const char* aName,
+                            const char16_t** aParams,
+                            uint32_t aParamsLength,
+@@ -827,19 +832,26 @@ nsCSPContext::logToConsole(const char* a
+     elem.mMsg = msg;
+     elem.mSourceName = PromiseFlatString(aSourceName);
+     elem.mSourceLine = PromiseFlatString(aSourceLine);
+     elem.mLineNumber = aLineNumber;
+     elem.mColumnNumber = aColumnNumber;
+     elem.mSeverityFlag = aSeverityFlag;
+     return;
+   }
++
++  bool privateWindow = false;
++  nsCOMPtr<nsIDocument> doc = do_QueryReferent(mLoadingContext);
++  if (doc) {
++    privateWindow = !!doc->NodePrincipal()->OriginAttributesRef().mPrivateBrowsingId;
++  }
++
+   CSP_LogLocalizedStr(aName, aParams, aParamsLength, aSourceName,
+                       aSourceLine, aLineNumber, aColumnNumber,
+-                      aSeverityFlag, "CSP", mInnerWindowID);
++                      aSeverityFlag, "CSP", mInnerWindowID, privateWindow);
+ }
+ 
+ /**
+  * Strip URI for reporting according to:
+  * http://www.w3.org/TR/CSP/#violation-reports
+  *
+  * @param aURI
+  *        The uri to be stripped for reporting
+diff --git a/dom/security/nsCSPUtils.cpp b/dom/security/nsCSPUtils.cpp
+--- a/dom/security/nsCSPUtils.cpp
++++ b/dom/security/nsCSPUtils.cpp
+@@ -125,17 +125,18 @@ CSP_LogStrMessage(const nsAString& aMsg)
+ void
+ CSP_LogMessage(const nsAString& aMessage,
+                const nsAString& aSourceName,
+                const nsAString& aSourceLine,
+                uint32_t aLineNumber,
+                uint32_t aColumnNumber,
+                uint32_t aFlags,
+                const char *aCategory,
+-               uint64_t aInnerWindowID)
++               uint64_t aInnerWindowID,
++               bool aFromPrivateWindow)
+ {
+   nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
+ 
+   nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
+ 
+   if (!console || !error) {
+     return;
+   }
+@@ -165,17 +166,17 @@ CSP_LogMessage(const nsAString& aMessage
+                                  aSourceLine, aLineNumber,
+                                  aColumnNumber, aFlags,
+                                  catStr, aInnerWindowID);
+   }
+   else {
+     rv = error->Init(cspMsg, aSourceName,
+                      aSourceLine, aLineNumber,
+                      aColumnNumber, aFlags,
+-                     aCategory);
++                     aCategory, aFromPrivateWindow);
+   }
+   if (NS_FAILED(rv)) {
+     return;
+   }
+   console->LogMessage(error);
+ }
+ 
+ /**
+@@ -186,23 +187,24 @@ CSP_LogLocalizedStr(const char* aName,
+                     const char16_t** aParams,
+                     uint32_t aLength,
+                     const nsAString& aSourceName,
+                     const nsAString& aSourceLine,
+                     uint32_t aLineNumber,
+                     uint32_t aColumnNumber,
+                     uint32_t aFlags,
+                     const char* aCategory,
+-                    uint64_t aInnerWindowID)
++                    uint64_t aInnerWindowID,
++                    bool aFromPrivateWindow)
+ {
+   nsAutoString logMsg;
+   CSP_GetLocalizedStr(aName, aParams, aLength, logMsg);
+   CSP_LogMessage(logMsg, aSourceName, aSourceLine,
+                  aLineNumber, aColumnNumber, aFlags,
+-                 aCategory, aInnerWindowID);
++                 aCategory, aInnerWindowID, aFromPrivateWindow);
+ }
+ 
+ /* ===== Helpers ============================ */
+ CSPDirective
+ CSP_ContentTypeToDirective(nsContentPolicyType aType)
+ {
+   switch (aType) {
+     case nsIContentPolicy::TYPE_IMAGE:
+diff --git a/dom/security/nsCSPUtils.h b/dom/security/nsCSPUtils.h
+--- a/dom/security/nsCSPUtils.h
++++ b/dom/security/nsCSPUtils.h
+@@ -29,33 +29,35 @@ void CSP_LogLocalizedStr(const char* aNa
+                          const char16_t** aParams,
+                          uint32_t aLength,
+                          const nsAString& aSourceName,
+                          const nsAString& aSourceLine,
+                          uint32_t aLineNumber,
+                          uint32_t aColumnNumber,
+                          uint32_t aFlags,
+                          const char* aCategory,
+-                         uint64_t aInnerWindowID);
++                         uint64_t aInnerWindowID,
++                         bool aFromPrivateWindow);
+ 
+ void CSP_GetLocalizedStr(const char* aName,
+                          const char16_t** aParams,
+                          uint32_t aLength,
+                          nsAString& outResult);
+ 
+ void CSP_LogStrMessage(const nsAString& aMsg);
+ 
+ void CSP_LogMessage(const nsAString& aMessage,
+                     const nsAString& aSourceName,
+                     const nsAString& aSourceLine,
+                     uint32_t aLineNumber,
+                     uint32_t aColumnNumber,
+                     uint32_t aFlags,
+                     const char* aCategory,
+-                    uint64_t aInnerWindowID);
++                    uint64_t aInnerWindowID,
++                    bool aFromPrivateWindow);
+ 
+ 
+ /* =============== Constant and Type Definitions ================== */
+ 
+ #define INLINE_STYLE_VIOLATION_OBSERVER_TOPIC        "violated base restriction: Inline Stylesheets will not apply"
+ #define INLINE_SCRIPT_VIOLATION_OBSERVER_TOPIC       "violated base restriction: Inline Scripts will not execute"
+ #define EVAL_VIOLATION_OBSERVER_TOPIC                "violated base restriction: Code will not be created from strings"
+ #define SCRIPT_NONCE_VIOLATION_OBSERVER_TOPIC        "Inline Script had invalid nonce"
+diff --git a/dom/security/nsMixedContentBlocker.cpp b/dom/security/nsMixedContentBlocker.cpp
+--- a/dom/security/nsMixedContentBlocker.cpp
++++ b/dom/security/nsMixedContentBlocker.cpp
+@@ -747,17 +747,18 @@ nsMixedContentBlocker::ShouldLoad(bool a
+     const char16_t* params[] = { reportSpec.get()};
+     CSP_LogLocalizedStr("blockAllMixedContent",
+                         params, ArrayLength(params),
+                         EmptyString(), // aSourceFile
+                         EmptyString(), // aScriptSample
+                         0, // aLineNumber
+                         0, // aColumnNumber
+                         nsIScriptError::errorFlag, "CSP",
+-                        document->InnerWindowID());
++                        document->InnerWindowID(),
++                        !!document->NodePrincipal()->OriginAttributesRef().mPrivateBrowsingId);
+     *aDecision = REJECT_REQUEST;
+     return NS_OK;
+   }
+ 
+   // Determine if the rootDoc is https and if the user decided to allow Mixed Content
+   bool rootHasSecureConnection = false;
+   bool allowMixedContent = false;
+   bool isRootDocShell = false;
+diff --git a/dom/websocket/WebSocket.cpp b/dom/websocket/WebSocket.cpp
+--- a/dom/websocket/WebSocket.cpp
++++ b/dom/websocket/WebSocket.cpp
+@@ -95,16 +95,17 @@ public:
+   , mOnCloseScheduled(false)
+   , mFailed(false)
+   , mDisconnectingOrDisconnected(false)
+   , mCloseEventWasClean(false)
+   , mCloseEventCode(nsIWebSocketChannel::CLOSE_ABNORMAL)
+   , mScriptLine(0)
+   , mScriptColumn(0)
+   , mInnerWindowID(0)
++  , mPrivateBrowsing(false)
+   , mWorkerPrivate(nullptr)
+ #ifdef DEBUG
+   , mHasWorkerHolderRegistered(false)
+ #endif
+   , mIsMainThread(true)
+   , mMutex("WebSocketImpl::mMutex")
+   , mWorkerShuttingDown(false)
+   {
+@@ -207,16 +208,17 @@ public:
+   //   was constructed.
+   // - the ID of the inner window where the script lives. Note that this may not
+   //   be the same as the Web Socket owner window.
+   // These attributes are used for error reporting.
+   nsCString mScriptFile;
+   uint32_t mScriptLine;
+   uint32_t mScriptColumn;
+   uint64_t mInnerWindowID;
++  bool mPrivateBrowsing;
+ 
+   WorkerPrivate* mWorkerPrivate;
+   nsAutoPtr<WorkerHolder> mWorkerHolder;
+ 
+ #ifdef DEBUG
+   // This is protected by mutex.
+   bool mHasWorkerHolderRegistered;
+ 
+@@ -386,17 +388,18 @@ WebSocketImpl::PrintErrorOnConsole(const
+                                        EmptyString(), mScriptLine,
+                                        mScriptColumn,
+                                        nsIScriptError::errorFlag, "Web Socket",
+                                        mInnerWindowID);
+   } else {
+     rv = errorObject->Init(message,
+                            NS_ConvertUTF8toUTF16(mScriptFile),
+                            EmptyString(), mScriptLine, mScriptColumn,
+-                           nsIScriptError::errorFlag, "Web Socket");
++                           nsIScriptError::errorFlag, "Web Socket",
++                           mPrivateBrowsing);
+   }
+ 
+   NS_ENSURE_SUCCESS_VOID(rv);
+ 
+   // print the error message directly to the JS console
+   rv = console->LogMessage(errorObject);
+   NS_ENSURE_SUCCESS_VOID(rv);
+ }
+@@ -1566,16 +1569,18 @@ WebSocketImpl::Init(JSContext* aCx,
+ 
+   // If we don't have aCx, we are window-less, so we don't have a
+   // inner-windowID. This can happen in sharedWorkers and ServiceWorkers or in
+   // DedicateWorkers created by JSM.
+   if (aCx) {
+     mInnerWindowID = nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(aCx);
+   }
+ 
++  mPrivateBrowsing = !!aPrincipal->OriginAttributesRef().mPrivateBrowsingId;
++
+   // parses the url
+   rv = ParseURL(PromiseFlatString(aURL));
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   nsCOMPtr<nsIDocument> originDoc = mWebSocket->GetDocumentIfCurrent();
+   if (!originDoc) {
+     rv = mWebSocket->CheckInnerWindowCorrectness();
+     NS_ENSURE_SUCCESS(rv, rv);
+@@ -1638,17 +1643,18 @@ WebSocketImpl::Init(JSContext* aCx,
+     const char16_t* params[] = { reportSpec.get(), u"wss" };
+     CSP_LogLocalizedStr("upgradeInsecureRequest",
+                         params, ArrayLength(params),
+                         EmptyString(), // aSourceFile
+                         EmptyString(), // aScriptSample
+                         0, // aLineNumber
+                         0, // aColumnNumber
+                         nsIScriptError::warningFlag, "CSP",
+-                        mInnerWindowID);
++                        mInnerWindowID,
++                        mPrivateBrowsing);
+   }
+ 
+   // Don't allow https:// to open ws://
+   if (!mIsServerSide && !mSecure &&
+       !Preferences::GetBool("network.websocket.allowInsecureFromHTTPS",
+                             false)) {
+     // Confirmed we are opening plain ws:// and want to prevent this from a
+     // secure context (e.g. https).
+diff --git a/js/ipc/JavaScriptParent.cpp b/js/ipc/JavaScriptParent.cpp
+--- a/js/ipc/JavaScriptParent.cpp
++++ b/js/ipc/JavaScriptParent.cpp
+@@ -142,17 +142,18 @@ JavaScriptParent::allowMessage(JSContext
+         nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
+         if (console && cx) {
+             nsAutoString filename;
+             uint32_t lineno = 0, column = 0;
+             nsJSUtils::GetCallingLocation(cx, filename, &lineno, &column);
+             nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
+             error->Init(NS_LITERAL_STRING("unsafe/forbidden CPOW usage"), filename,
+                         EmptyString(), lineno, column,
+-                        nsIScriptError::warningFlag, "chrome javascript");
++                        nsIScriptError::warningFlag, "chrome javascript",
++                        false /* from private window */);
+             console->LogMessage(error);
+         } else {
+             NS_WARNING("Unsafe synchronous IPC message");
+         }
+     }
+ 
+     return true;
+ }
+diff --git a/js/xpconnect/src/XPCWrappedNativeInfo.cpp b/js/xpconnect/src/XPCWrappedNativeInfo.cpp
+--- a/js/xpconnect/src/XPCWrappedNativeInfo.cpp
++++ b/js/xpconnect/src/XPCWrappedNativeInfo.cpp
+@@ -245,17 +245,18 @@ XPCNativeInterface::NewInstance(nsIInter
+             nsPrintfCString errorMsg("Use of %s in content process is deprecated.", intfNameChars);
+ 
+             nsAutoString filename;
+             uint32_t lineno = 0, column = 0;
+             nsJSUtils::GetCallingLocation(cx, filename, &lineno, &column);
+             nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
+             error->Init(NS_ConvertUTF8toUTF16(errorMsg),
+                         filename, EmptyString(),
+-                        lineno, column, nsIScriptError::warningFlag, "chrome javascript");
++                        lineno, column, nsIScriptError::warningFlag, "chrome javascript",
++                        false /* from private window */);
+             console->LogMessage(error);
+         }
+     }
+ 
+     if (NS_FAILED(aInfo->GetMethodCount(&methodCount)) ||
+         NS_FAILED(aInfo->GetConstantCount(&constCount)))
+         return nullptr;
+ 
+diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp
+--- a/netwerk/base/nsNetUtil.cpp
++++ b/netwerk/base/nsNetUtil.cpp
+@@ -2788,17 +2788,18 @@ NS_ShouldSecureUpgrade(nsIURI* aURI,
+         uint32_t innerWindowId = aLoadInfo->GetInnerWindowID();
+         CSP_LogLocalizedStr("upgradeInsecureRequest",
+                             params, ArrayLength(params),
+                             EmptyString(), // aSourceFile
+                             EmptyString(), // aScriptSample
+                             0, // aLineNumber
+                             0, // aColumnNumber
+                             nsIScriptError::warningFlag, "CSP",
+-                            innerWindowId);
++                            innerWindowId,
++                            !!aLoadInfo->GetOriginAttributes().mPrivateBrowsingId);
+ 
+         aShouldUpgrade = true;
+         return NS_OK;
+       }
+     }
+ 
+     // enforce Strict-Transport-Security
+     nsISiteSecurityService* sss = gHttpHandler->GetSSService();
+diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
+--- a/netwerk/protocol/http/HttpChannelChild.cpp
++++ b/netwerk/protocol/http/HttpChannelChild.cpp
+@@ -3883,17 +3883,19 @@ HttpChannelChild::RecvLogBlockedCORSRequ
+   return IPC_OK();
+ }
+ 
+ NS_IMETHODIMP
+ HttpChannelChild::LogBlockedCORSRequest(const nsAString & aMessage)
+ {
+   if (mLoadInfo) {
+     uint64_t innerWindowID = mLoadInfo->GetInnerWindowID();
+-    nsCORSListenerProxy::LogBlockedCORSRequest(innerWindowID, aMessage);
++    bool privateBrowsing = !!mLoadInfo->GetOriginAttributes().mPrivateBrowsingId;
++    nsCORSListenerProxy::LogBlockedCORSRequest(innerWindowID, privateBrowsing,
++                                               aMessage);
+   }
+   return NS_OK;
+ }
+ 
+ void
+ HttpChannelChild::MaybeCallSynthesizedCallback()
+ {
+   if (!mSynthesizedCallback) {
+diff --git a/netwerk/protocol/http/nsCORSListenerProxy.cpp b/netwerk/protocol/http/nsCORSListenerProxy.cpp
+--- a/netwerk/protocol/http/nsCORSListenerProxy.cpp
++++ b/netwerk/protocol/http/nsCORSListenerProxy.cpp
+@@ -92,19 +92,28 @@ LogBlockedRequest(nsIRequest* aRequest,
+       rv = aCreatingChannel->LogBlockedCORSRequest(msg);
+       if (NS_SUCCEEDED(rv)) {
+         return;
+       }
+     }
+     NS_WARNING("Failed to log blocked cross-site request to web console from parent->child, falling back to browser console");
+   }
+ 
++  bool privateBrowsing = false;
++  if (aRequest) {
++    nsCOMPtr<nsILoadGroup> loadGroup;
++    rv = aRequest->GetLoadGroup(getter_AddRefs(loadGroup));
++    NS_ENSURE_SUCCESS_VOID(rv);
++    privateBrowsing = nsContentUtils::IsInPrivateBrowsing(loadGroup);
++  }
++
+   // log message ourselves
+   uint64_t innerWindowID = nsContentUtils::GetInnerWindowID(aRequest);
+-  nsCORSListenerProxy::LogBlockedCORSRequest(innerWindowID, msg);
++  nsCORSListenerProxy::LogBlockedCORSRequest(innerWindowID, privateBrowsing,
++                                             msg);
+ }
+ 
+ //////////////////////////////////////////////////////////////////////////
+ // Preflight cache
+ 
+ class nsPreflightCache
+ {
+ public:
+@@ -1569,16 +1578,17 @@ nsCORSListenerProxy::StartCORSPreflight(
+   preflightChannel.forget(aPreflightChannel);
+ 
+   return NS_OK;
+ }
+ 
+ // static
+ void
+ nsCORSListenerProxy::LogBlockedCORSRequest(uint64_t aInnerWindowID,
++                                           bool aPrivateBrowsing,
+                                            const nsAString& aMessage)
+ {
+   nsresult rv = NS_OK;
+ 
+   // Build the error object and log it to the console
+   nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv));
+   if (NS_FAILED(rv)) {
+     NS_WARNING("Failed to log blocked cross-site request (no console)");
+@@ -1606,16 +1616,17 @@ nsCORSListenerProxy::LogBlockedCORSReque
+   }
+   else {
+     rv = scriptError->Init(aMessage,
+                            EmptyString(), // sourceName
+                            EmptyString(), // sourceLine
+                            0,             // lineNumber
+                            0,             // columnNumber
+                            nsIScriptError::warningFlag,
+-                           "CORS");
++                           "CORS",
++                           aPrivateBrowsing);
+   }
+   if (NS_FAILED(rv)) {
+     NS_WARNING("Failed to log blocked cross-site request (scriptError init failed)");
+     return;
+   }
+   console->LogMessage(scriptError);
+ }
+diff --git a/netwerk/protocol/http/nsCORSListenerProxy.h b/netwerk/protocol/http/nsCORSListenerProxy.h
+--- a/netwerk/protocol/http/nsCORSListenerProxy.h
++++ b/netwerk/protocol/http/nsCORSListenerProxy.h
+@@ -70,16 +70,17 @@ public:
+   MOZ_MUST_USE nsresult Init(nsIChannel* aChannel,
+                              DataURIHandling aAllowDataURI);
+ 
+   void SetInterceptController(nsINetworkInterceptController* aInterceptController);
+ 
+   // When CORS blocks a request, log the message to the web console, or the
+   // browser console if no valid inner window ID is found.
+   static void LogBlockedCORSRequest(uint64_t aInnerWindowID,
++                                    bool aPrivateBrowsing,
+                                     const nsAString& aMessage);
+ private:
+   // Only HttpChannelParent can call RemoveFromCorsPreflightCache
+   friend class mozilla::net::HttpChannelParent;
+   // Only nsHttpChannel can invoke CORS preflights
+   friend class mozilla::net::nsHttpChannel;
+ 
+   static void RemoveFromCorsPreflightCache(nsIURI* aURI,
+diff --git a/security/manager/ssl/SSLServerCertVerification.cpp b/security/manager/ssl/SSLServerCertVerification.cpp
+--- a/security/manager/ssl/SSLServerCertVerification.cpp
++++ b/security/manager/ssl/SSLServerCertVerification.cpp
+@@ -202,17 +202,18 @@ namespace {
+ void
+ LogInvalidCertError(nsNSSSocketInfo* socketInfo,
+                     PRErrorCode errorCode,
+                     ::mozilla::psm::SSLErrorMessageType errorMessageType)
+ {
+   nsString message;
+   socketInfo->GetErrorLogMessage(errorCode, errorMessageType, message);
+   if (!message.IsEmpty()) {
+-    nsContentUtils::LogSimpleConsoleError(message, "SSL");
++    nsContentUtils::LogSimpleConsoleError(message, "SSL",
++                                          !!socketInfo->GetOriginAttributes().mPrivateBrowsingId);
+   }
+ }
+ 
+ // Dispatched to the STS thread to notify the infoObject of the verification
+ // result.
+ //
+ // This will cause the PR_Poll in the STS thread to return, so things work
+ // correctly even if the STS thread is blocked polling (only) on the file
+diff --git a/security/manager/ssl/nsNSSCallbacks.cpp b/security/manager/ssl/nsNSSCallbacks.cpp
+--- a/security/manager/ssl/nsNSSCallbacks.cpp
++++ b/security/manager/ssl/nsNSSCallbacks.cpp
+@@ -1481,14 +1481,15 @@ void HandshakeCallback(PRFileDesc* fd, v
+   // we should set a flag on the channel that higher (UI) level code can check
+   // to log the warning. In particular, these warnings should go to the web
+   // console instead of to the error console. Also, the warning is not
+   // localized.
+   if (!siteSupportsSafeRenego) {
+     NS_ConvertASCIItoUTF16 msg(infoObject->GetHostName());
+     msg.AppendLiteral(" : server does not support RFC 5746, see CVE-2009-3555");
+ 
+-    nsContentUtils::LogSimpleConsoleError(msg, "SSL");
++    nsContentUtils::LogSimpleConsoleError(msg, "SSL",
++                                          !!infoObject->GetOriginAttributes().mPrivateBrowsingId);
+   }
+ 
+   infoObject->NoteTimeUntilReady();
+   infoObject->SetHandshakeCompleted();
+ }
+diff --git a/security/manager/ssl/nsNSSIOLayer.cpp b/security/manager/ssl/nsNSSIOLayer.cpp
+--- a/security/manager/ssl/nsNSSIOLayer.cpp
++++ b/security/manager/ssl/nsNSSIOLayer.cpp
+@@ -717,17 +717,18 @@ nsHandleSSLError(nsNSSSocketInfo* socket
+   }
+ 
+   // We must cancel first, which sets the error code.
+   socketInfo->SetCanceled(err, SSLErrorMessageType::Plain);
+   nsAutoString errorString;
+   socketInfo->GetErrorLogMessage(err, errtype, errorString);
+ 
+   if (!errorString.IsEmpty()) {
+-    nsContentUtils::LogSimpleConsoleError(errorString, "SSL");
++    nsContentUtils::LogSimpleConsoleError(errorString, "SSL",
++                                          !!socketInfo->GetOriginAttributes().mPrivateBrowsingId);
+   }
+ }
+ 
+ namespace {
+ 
+ enum Operation { reading, writing, not_reading_or_writing };
+ 
+ int32_t checkHandshake(int32_t bytesTransfered, bool wasReading,
+diff --git a/storage/mozStorageHelper.h b/storage/mozStorageHelper.h
+--- a/storage/mozStorageHelper.h
++++ b/storage/mozStorageHelper.h
+@@ -218,17 +218,18 @@ protected:
+                                                                                    \
+     if (cs) {                                                                      \
+       nsCString msg(__FUNCTION__);                                                 \
+       msg.AppendLiteral(" is deprecated and will be removed soon.");               \
+                                                                                    \
+       nsCOMPtr<nsIScriptError> e = do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);   \
+       if (e && NS_SUCCEEDED(e->Init(NS_ConvertUTF8toUTF16(msg), EmptyString(),     \
+                                     EmptyString(), 0, 0,                           \
+-                                    nsIScriptError::errorFlag, "Storage"))) {      \
++                                    nsIScriptError::errorFlag, "Storage",          \
++                                    false))) {                                     \
+         cs->LogMessage(e);                                                         \
+       }                                                                            \
+     }                                                                              \
+   }                                                                                \
+   if (NS_IsMainThread()) {                                                         \
+     nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());            \
+     if (xpc) {                                                                     \
+       mozilla::Unused << xpc->DebugDumpJSStack(false, false, false);               \
+diff --git a/toolkit/components/places/nsPlacesMacros.h b/toolkit/components/places/nsPlacesMacros.h
+--- a/toolkit/components/places/nsPlacesMacros.h
++++ b/toolkit/components/places/nsPlacesMacros.h
+@@ -70,13 +70,14 @@
+   nsCString msg(__FUNCTION__);                                                 \
+   msg.AppendLiteral(" is deprecated and will be removed in the next version.");\
+   NS_WARNING(msg.get());                                                       \
+   nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);\
+   if (cs) {                                                                    \
+     nsCOMPtr<nsIScriptError> e = do_CreateInstance(NS_SCRIPTERROR_CONTRACTID); \
+     if (e && NS_SUCCEEDED(e->Init(NS_ConvertUTF8toUTF16(msg), EmptyString(),   \
+                                   EmptyString(), 0, 0,                         \
+-                                  nsIScriptError::errorFlag, "Places"))) {     \
++                                  nsIScriptError::errorFlag, "Places",         \
++                                  false))) {                                   \
+       cs->LogMessage(e);                                                       \
+     }                                                                          \
+   }                                                                            \
+   PR_END_MACRO
+diff --git a/toolkit/components/telemetry/TelemetryCommon.cpp b/toolkit/components/telemetry/TelemetryCommon.cpp
+--- a/toolkit/components/telemetry/TelemetryCommon.cpp
++++ b/toolkit/components/telemetry/TelemetryCommon.cpp
+@@ -111,17 +111,18 @@ LogToBrowserConsole(uint32_t aLogLevel, 
+ 
+   nsCOMPtr<nsIConsoleService> console(do_GetService("@mozilla.org/consoleservice;1"));
+   if (!console) {
+     NS_WARNING("Failed to log message to console.");
+     return;
+   }
+ 
+   nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
+-  error->Init(aMsg, EmptyString(), EmptyString(), 0, 0, aLogLevel, "chrome javascript");
++  error->Init(aMsg, EmptyString(), EmptyString(), 0, 0, aLogLevel,
++              "chrome javascript", false /* from private window */);
+   console->LogMessage(error);
+ }
+ 
+ const char*
+ GetNameForProcessID(ProcessID process)
+ {
+   MOZ_ASSERT(process < ProcessID::Count);
+   return ProcessIDToString[static_cast<uint32_t>(process)];
+diff --git a/xpcom/components/ManifestParser.cpp b/xpcom/components/ManifestParser.cpp
+--- a/xpcom/components/ManifestParser.cpp
++++ b/xpcom/components/ManifestParser.cpp
+@@ -186,17 +186,18 @@ LogMessageWithContext(FileLocation& aFil
+     do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+   if (!console) {
+     return;
+   }
+ 
+   nsresult rv = error->Init(NS_ConvertUTF8toUTF16(formatted.get()),
+                             NS_ConvertUTF8toUTF16(file), EmptyString(),
+                             aLineNumber, 0, nsIScriptError::warningFlag,
+-                            "chrome registration");
++                            "chrome registration",
++                            false /* from private window */);
+   if (NS_FAILED(rv)) {
+     return;
+   }
+ 
+   console->LogMessage(error);
+ }
+ 
+ /**
+diff --git a/xpcom/ds/nsObserverService.cpp b/xpcom/ds/nsObserverService.cpp
+--- a/xpcom/ds/nsObserverService.cpp
++++ b/xpcom/ds/nsObserverService.cpp
+@@ -216,17 +216,18 @@ nsObserverService::AddObserver(nsIObserv
+   // child process; see bug 1269765.
+   if (mozilla::net::IsNeckoChild() && !strncmp(aTopic, "http-on-", 8) &&
+       strcmp(aTopic, "http-on-opening-request") &&
+       strcmp(aTopic, "http-on-stop-request")) {
+     nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
+     nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
+     error->Init(NS_LITERAL_STRING("http-on-* observers only work in the parent process"),
+                 EmptyString(), EmptyString(), 0, 0,
+-                nsIScriptError::warningFlag, "chrome javascript");
++                nsIScriptError::warningFlag, "chrome javascript",
++                false /* from private window */);
+     console->LogMessage(error);
+ 
+     return NS_ERROR_NOT_IMPLEMENTED;
+   }
+ 
+   nsObserverList* observerList = mObserverTopicTable.PutEntry(aTopic);
+   if (!observerList) {
+     return NS_ERROR_OUT_OF_MEMORY;

+ 3 - 3
mozilla-release/patches/1443081-16-client-webconsole-61a1.patch

@@ -2,7 +2,7 @@
 # User J. Ryan Stinnett <jryans@gmail.com>
 # Date 1520879078 18000
 # Node ID 49cce2c9e2ab21606a9abcdc0ab0af991806957f
-# Parent  80e19aadc2ac8378ca4ee8ca7e428d73386aafba
+# Parent  a999145d2aa1a9fb12779f163f62b483d59ce1a9
 Bug 1443081 - Apply spacing via `eslint --fix` for DevTools - part 16. r=jdescottes
 
 MozReview-Commit-ID: 2RVNt140Zte
@@ -5428,11 +5428,11 @@ diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browse
 @@ -22,17 +22,17 @@ const TEST_VIOLATION = "http://example.c
  const CSP_VIOLATION_MSG =
    "Content Security Policy: The page\u2019s settings blocked the loading of a resource " +
-   "at http://some.example.com/cspro.png (\u201cimg-src http://example.com\u201d).";
+   "at http://some.example.com/cspro.png (\u201cimg-src\u201d).";
  const CSP_REPORT_MSG =
    "Content Security Policy: The page\u2019s settings observed the loading of a " +
    "resource at http://some.example.com/cspro.js " +
-   "(\u201cscript-src http://example.com\u201d). A CSP report is being sent.";
+   "(\u201cscript-src\u201d). A CSP report is being sent.";
  
 -add_task(async function () {
 +add_task(async function() {

+ 11 - 11
mozilla-release/patches/1445302-61a1.patch

@@ -2,7 +2,7 @@
 # User Miko Mynttinen <mikokm@gmail.com>
 # Date 1520949093 -3600
 # Node ID bceb565cfe14de56a10472e4965b4e9283b24307
-# Parent  bc7a09756e383fd053a0d5b56671b5f4f55afe56
+# Parent  8ce70b68946bcaa734cf9e2262548fbc5f163334
 Bug 1445302 - Replace TArray.RemoveElementAt(TArray.Length() - 1) pattern with TArray.RemoveLastElement() or TArray.PopLastElement() r=froydnj
 
 MozReview-Commit-ID: rGjabnP2iz
@@ -93,7 +93,7 @@ diff --git a/dom/base/nsDocumentEncoder.cpp b/dom/base/nsDocumentEncoder.cpp
 diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp
 --- a/dom/base/nsFrameMessageManager.cpp
 +++ b/dom/base/nsFrameMessageManager.cpp
-@@ -1099,17 +1099,17 @@ nsFrameMessageManager::ReceiveMessage(ns
+@@ -1100,17 +1100,17 @@ nsFrameMessageManager::ReceiveMessage(ns
            continue;
          }
          if (aRetVal) {
@@ -110,8 +110,8 @@ diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager
              if (console) {
                nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
                error->Init(msg, EmptyString(), EmptyString(),
-                           0, 0, nsIScriptError::warningFlag, "chrome javascript");
-               console->LogMessage(error);
+                           0, 0, nsIScriptError::warningFlag, "chrome javascript",
+                           false /* from private window */);
 diff --git a/dom/base/nsHTMLContentSerializer.cpp b/dom/base/nsHTMLContentSerializer.cpp
 --- a/dom/base/nsHTMLContentSerializer.cpp
 +++ b/dom/base/nsHTMLContentSerializer.cpp
@@ -336,7 +336,7 @@ diff --git a/dom/xslt/xslt/txExecutionState.cpp b/dom/xslt/xslt/txExecutionState
 diff --git a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
 --- a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
 +++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
-@@ -824,17 +824,17 @@ mozInlineSpellWordUtil::BuildSoftText()
+@@ -832,17 +832,17 @@ mozInlineSpellWordUtil::BuildSoftText()
          int32_t len = lastOffsetInNode - firstOffsetInNode;
          mSoftTextDOMMapping.AppendElement(
            DOMTextMapping(NodeOffset(node, firstOffsetInNode), mSoftText.Length(), len));
@@ -399,7 +399,7 @@ diff --git a/gfx/thebes/gfxContext.cpp b/gfx/thebes/gfxContext.cpp
  
  // drawing
  void
-@@ -606,17 +606,17 @@ gfxContext::Clip()
+@@ -604,17 +604,17 @@ gfxContext::Clip()
    }
  }
  
@@ -719,7 +719,7 @@ diff --git a/layout/generic/TextDrawTarget.h b/layout/generic/TextDrawTarget.h
 diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp
 --- a/layout/generic/nsFrame.cpp
 +++ b/layout/generic/nsFrame.cpp
-@@ -12180,17 +12180,17 @@ DR_FrameTreeNode* DR_State::CreateTreeNo
+@@ -12190,17 +12190,17 @@ DR_FrameTreeNode* DR_State::CreateTreeNo
    FindMatchingRule(*newNode);
  
    newNode->mIndent = mIndent;
@@ -763,7 +763,7 @@ diff --git a/layout/painting/RetainedDisplayListBuilder.cpp b/layout/painting/Re
 diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h
 --- a/layout/painting/nsDisplayList.h
 +++ b/layout/painting/nsDisplayList.h
-@@ -6708,18 +6708,17 @@ private:
+@@ -6737,18 +6737,17 @@ private:
    void ResolveFlattening()
    {
      // Handle the case where we reach the end of a nested list, or the current
@@ -862,7 +862,7 @@ diff --git a/netwerk/cache2/CacheIndexIterator.cpp b/netwerk/cache2/CacheIndexIt
 diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
 --- a/netwerk/protocol/http/nsHttpChannel.cpp
 +++ b/netwerk/protocol/http/nsHttpChannel.cpp
-@@ -8052,18 +8052,17 @@ nsHttpChannel::OnRedirectVerifyCallback(
+@@ -8032,18 +8032,17 @@ nsHttpChannel::OnRedirectVerifyCallback(
      mWaitingForRedirectCallback = false;
  
      if (mCanceled && NS_SUCCEEDED(result))
@@ -885,7 +885,7 @@ diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsH
 diff --git a/parser/html/nsHtml5Highlighter.cpp b/parser/html/nsHtml5Highlighter.cpp
 --- a/parser/html/nsHtml5Highlighter.cpp
 +++ b/parser/html/nsHtml5Highlighter.cpp
-@@ -700,17 +700,17 @@ nsHtml5Highlighter::Push(nsIAtom* aName,
+@@ -705,17 +705,17 @@ nsHtml5Highlighter::Push(nsIAtom* aName,
    mOpQueue.AppendElement()->Init(eTreeOpAppend, elt, CurrentNode());
    mStack.AppendElement(elt);
  }
@@ -952,7 +952,7 @@ diff --git a/widget/cocoa/TextInputHandler.h b/widget/cocoa/TextInputHandler.h
 diff --git a/widget/windows/TSFTextStore.cpp b/widget/windows/TSFTextStore.cpp
 --- a/widget/windows/TSFTextStore.cpp
 +++ b/widget/windows/TSFTextStore.cpp
-@@ -4782,17 +4782,17 @@ TSFTextStore::RecordCompositionStartActi
+@@ -4950,17 +4950,17 @@ TSFTextStore::RecordCompositionStartActi
    // compositionend and start composition normally.
    if (!aPreserveSelection &&
        WasTextInsertedWithoutCompositionAt(aStart, aLength)) {

+ 73 - 0
mozilla-release/patches/1447210-1-61a1.patch

@@ -0,0 +1,73 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1521876061 -3600
+# Node ID 5a19ca99d1507b291d0ecfdada3af8ab88ca8956
+# Parent  1d05da548136ea95b82418355c3327e2eeb4fc5f
+Bug 1447210 - Upper-case log levels for Console.createInstance(), r=bgrins
+
+diff --git a/dom/console/tests/console.jsm b/dom/console/tests/console.jsm
+--- a/dom/console/tests/console.jsm
++++ b/dom/console/tests/console.jsm
+@@ -14,14 +14,14 @@ this.ConsoleTest = {
+       innerID: "CUSTOM INNER",
+       dump: dumpFunction,
+       prefix: "_PREFIX_",
+     });
+ 
+     c.log("Hello world!");
+     c.trace("Hello world!");
+ 
+-    console.createInstance({ innerID: "LEVEL", maxLogLevel: "off" }).log("Invisible!");
+-    console.createInstance({ innerID: "LEVEL",  maxLogLevel: "all" }).log("Hello world!");
++    console.createInstance({ innerID: "LEVEL", maxLogLevel: "Off" }).log("Invisible!");
++    console.createInstance({ innerID: "LEVEL",  maxLogLevel: "All" }).log("Hello world!");
+     console.createInstance({ innerID: "LEVEL", maxLogLevelPref: "foo.pref" }).log("Invisible!");
+     console.createInstance({ innerID: "LEVEL", maxLogLevelPref: "pref.test.console" }).log("Hello world!");
+   }
+ };
+diff --git a/dom/webidl/Console.webidl b/dom/webidl/Console.webidl
+--- a/dom/webidl/Console.webidl
++++ b/dom/webidl/Console.webidl
+@@ -152,18 +152,18 @@ interface ConsoleInstance {
+ 
+   void profile(any... data);
+   void profileEnd(any... data);
+ };
+ 
+ callback ConsoleInstanceDumpCallback = void (DOMString message);
+ 
+ enum ConsoleLogLevel {
+-  "all", "debug", "log", "info", "clear", "trace", "timeEnd", "time", "group",
+-  "groupEnd", "profile", "profileEnd", "dir", "dirxml", "warn", "error", "off"
++  "All", "Debug", "Log", "Info", "Clear", "Trace", "TimeEnd", "Time", "Group",
++  "GroupEnd", "Profile", "ProfileEnd", "Dir", "Dirxml", "Warn", "Error", "Off"
+ };
+ 
+ dictionary ConsoleInstanceOptions {
+   // An optional function to intercept all strings written to stdout.
+   ConsoleInstanceDumpCallback dump;
+ 
+   // An optional prefix string to be printed before the actual logged message.
+   DOMString prefix = "";
+diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
+--- a/modules/libpref/init/all.js
++++ b/modules/libpref/init/all.js
+@@ -5247,17 +5247,17 @@ pref("dom.vibrator.max_vibrate_list_len"
+ 
+ // Streams API
+ pref("dom.streams.enabled", false);
+ 
+ // Push
+ 
+ pref("dom.push.enabled", false);
+ 
+-pref("dom.push.loglevel", "error");
++pref("dom.push.loglevel", "Error");
+ 
+ pref("dom.push.serverURL", "wss://push.services.mozilla.com/");
+ pref("dom.push.userAgentID", "");
+ 
+ // The maximum number of push messages that a service worker can receive
+ // without user interaction.
+ pref("dom.push.maxQuotaPerSubscription", 16);
+ 

+ 75 - 0
mozilla-release/patches/1447210-2-61a1.patch

@@ -0,0 +1,75 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1521876061 -3600
+# Node ID 2acdab79292680b9764ad907d4ca67f9aa8bb49d
+# Parent  ef603ab3c4a4d68670913d1e8061c0b91ebc331f
+Bug 1447210 - Warning messages if console level pref doesn't exist, r=bgrins
+
+diff --git a/dom/console/ConsoleInstance.cpp b/dom/console/ConsoleInstance.cpp
+--- a/dom/console/ConsoleInstance.cpp
++++ b/dom/console/ConsoleInstance.cpp
+@@ -17,32 +17,43 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(Console
+ 
+ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ConsoleInstance)
+   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_END
+ 
+ namespace {
+ 
+ ConsoleLogLevel
+-PrefToValue(const nsCString& aPref)
++PrefToValue(const nsAString& aPref)
+ {
+   if (!NS_IsMainThread()) {
+     NS_WARNING("Console.maxLogLevelPref is not supported on workers!");
+     return ConsoleLogLevel::All;
+   }
+ 
++  NS_ConvertUTF16toUTF8 pref(aPref);
+   nsAutoCString value;
+-  nsresult rv = Preferences::GetCString(aPref.get(), value);
++  nsresult rv = Preferences::GetCString(pref.get(), value);
+   if (NS_WARN_IF(NS_FAILED(rv))) {
++    nsString message;
++    message.AssignLiteral("Console.maxLogLevelPref used with a non-existing pref: ");
++    message.Append(aPref);
++
++    nsContentUtils::LogSimpleConsoleError(message, "chrome", false);
+     return ConsoleLogLevel::All;
+   }
+ 
+   int index = FindEnumStringIndexImpl(value.get(), value.Length(),
+                                       ConsoleLogLevelValues::strings);
+   if (NS_WARN_IF(index < 0)) {
++    nsString message;
++    message.AssignLiteral("Invalid Console.maxLogLevelPref value: ");
++    message.Append(NS_ConvertUTF8toUTF16(value));
++
++    nsContentUtils::LogSimpleConsoleError(message, "chrome", false);
+     return ConsoleLogLevel::All;
+   }
+ 
+   MOZ_ASSERT(index < (int)ConsoleLogLevel::EndGuard_);
+   return static_cast<ConsoleLogLevel>(index);
+ }
+ 
+ } // anonymous
+@@ -66,17 +77,17 @@ ConsoleInstance::ConsoleInstance(const C
+   mConsole->mChromeInstance = true;
+ 
+   if (aOptions.mMaxLogLevel.WasPassed()) {
+     mConsole->mMaxLogLevel = aOptions.mMaxLogLevel.Value();
+   }
+ 
+   if (!aOptions.mMaxLogLevelPref.IsEmpty()) {
+     mConsole->mMaxLogLevel =
+-      PrefToValue(NS_ConvertUTF16toUTF8(aOptions.mMaxLogLevelPref));
++      PrefToValue(aOptions.mMaxLogLevelPref);
+   }
+ }
+ 
+ ConsoleInstance::~ConsoleInstance()
+ {}
+ 
+ JSObject*
+ ConsoleInstance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)

+ 45 - 0
mozilla-release/patches/1447422-61a1.patch

@@ -0,0 +1,45 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1521629847 -3600
+# Node ID 59a42f4b6ef6e4134f96428cc667571027785635
+# Parent  0f4499ed8d0fd6f613e218262511d2e5ce4d0cc9
+Bug 1447422 - Better check on aDocument in nsContentUtils::WarnScriptWasIgnored, r=smaug
+
+diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
+--- a/dom/base/nsContentUtils.cpp
++++ b/dom/base/nsContentUtils.cpp
+@@ -5857,27 +5857,30 @@ nsContentUtils::GetMostRecentNonPBWindow
+   return pwindow.forget();
+ }
+ 
+ /* static */
+ void
+ nsContentUtils::WarnScriptWasIgnored(nsIDocument* aDocument)
+ {
+   nsAutoString msg;
++  bool privateBrowsing = false;
++
+   if (aDocument) {
+     nsCOMPtr<nsIURI> uri = aDocument->GetDocumentURI();
+     if (uri) {
+       msg.Append(NS_ConvertUTF8toUTF16(uri->GetSpecOrDefault()));
+       msg.AppendLiteral(" : ");
+     }
+-  }
++    privateBrowsing =
++      !!aDocument->NodePrincipal()->OriginAttributesRef().mPrivateBrowsingId;
++  }
++
+   msg.AppendLiteral("Unable to run script because scripts are blocked internally.");
+-
+-  LogSimpleConsoleError(msg, "DOM",
+-                        !!aDocument->NodePrincipal()->OriginAttributesRef().mPrivateBrowsingId);
++  LogSimpleConsoleError(msg, "DOM", privateBrowsing);
+ }
+ 
+ /* static */
+ void
+ nsContentUtils::AddScriptRunner(already_AddRefed<nsIRunnable> aRunnable)
+ {
+   nsCOMPtr<nsIRunnable> runnable = aRunnable;
+   if (!runnable) {

+ 12 - 12
mozilla-release/patches/1762733-removepluginprefs-25312.patch

@@ -1,7 +1,7 @@
 # HG changeset patch
 # User Frank-Rainer Grahl <frgrahl@gmx.net>
 # Date 1648602379 -7200
-# Parent  6b6e369060ebac5dcd9d24792ad96f2aa4031eed
+# Parent  c87c54bd2ae74c2e4180fac0c76c18d87ce59465
 Bug 1762733 - Remove obsolete plugin prefs and code. r=IanN a=IanN
 
 SeaMonkey release branch only.
@@ -296,7 +296,7 @@ diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
  pref("privacy.permissionPrompts.showCloseButton", false);
  // Enforce tracking protection in all modes
  pref("privacy.trackingprotection.enabled",  false);
-@@ -2788,17 +2770,16 @@ pref("font.name-list.monospace.x-math", 
+@@ -2787,17 +2769,16 @@ pref("font.name-list.monospace.x-math", 
  // Some CJK fonts have bad underline offset, their CJK character glyphs are overlapped (or adjoined)  to its underline.
  // These fonts are ignored the underline offset, instead of it, the underline is lowered to bottom of its em descent.
  pref("font.blacklist.underline_offset", "FangSong,Gulim,GulimChe,MingLiU,MingLiU-ExtB,MingLiU_HKSCS,MingLiU-HKSCS-ExtB,MS Gothic,MS Mincho,MS PGothic,MS PMincho,MS UI Gothic,PMingLiU,PMingLiU-ExtB,SimHei,SimSun,SimSun-ExtB,Hei,Kai,Apple LiGothic,Apple LiSung,Osaka");
@@ -313,8 +313,8 @@ diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
  pref("security.csp.enable", true);
  pref("security.csp.experimentalEnabled", false);
  pref("security.csp.enableStrictDynamic", true);
- 
-@@ -3415,19 +3396,16 @@ pref("layout.animation.prerender.partial
+ #ifdef NIGHTLY_BUILD
+@@ -3419,19 +3400,16 @@ pref("layout.animation.prerender.partial
  pref("layout.animation.prerender.viewport-ratio-limit-x", "1.125");
  pref("layout.animation.prerender.viewport-ratio-limit-y", "1.125");
  pref("layout.animation.prerender.absolute-limit-x", 4096);
@@ -334,7 +334,7 @@ diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
  // See http://bugzilla.mozilla.org/show_bug.cgi?id=169483 for further details...
  pref("viewmanager.do_doublebuffering", true);
  
-@@ -3462,98 +3440,30 @@ pref("input_event_queue.default_duration
+@@ -3466,98 +3444,30 @@ pref("input_event_queue.default_duration
  pref("input_event_queue.count_for_prediction", 9);
  
  // Hang monitor timeout after which we kill the browser, in seconds
@@ -434,7 +434,7 @@ diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
  
  // WebExtensions only support a single extension process.
  pref("dom.ipc.processCount.extension", 1);
-@@ -4091,20 +4001,16 @@ pref("slider.snapMultiplier", 6);
+@@ -4095,20 +4005,16 @@ pref("slider.snapMultiplier", 6);
  
  // print_extra_margin enables platforms to specify an extra gap or margin
  // around the content of the page for Print Preview only
@@ -455,7 +455,7 @@ diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
  // use touch keyboard for URL when you set focus to the URL bar, you can
  // set this to false.  Then, you'll see, e.g., ".com" key on the keyboard.
  // However, if you set this to false, such IMEs set its open state to "closed"
-@@ -5748,17 +5654,16 @@ pref("urlclassifier.blockedTable", "test
+@@ -5752,17 +5658,16 @@ pref("urlclassifier.blockedTable", "test
  // Flash blocking tables
  pref("urlclassifier.flashAllowTable", "allow-flashallow-digest256");
  pref("urlclassifier.flashAllowExceptTable", "except-flashallow-digest256");
@@ -538,7 +538,7 @@ diff --git a/testing/talos/talos/config.py b/testing/talos/talos/config.py
 diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json
 --- a/toolkit/components/telemetry/Histograms.json
 +++ b/toolkit/components/telemetry/Histograms.json
-@@ -1944,71 +1944,16 @@
+@@ -1935,71 +1935,16 @@
      "record_in_processes": ["main", "content"],
      "expires_in_version": "50",
      "kind": "exponential",
@@ -610,7 +610,7 @@ diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/t
      "n_buckets": 10,
      "description": "Time spent on SQLite open() (ms)"
    },
-@@ -5534,45 +5479,16 @@
+@@ -5525,45 +5470,16 @@
    "PDF_VIEWER_TIME_TO_VIEW_MS": {
      "record_in_processes": ["main", "content"],
      "expires_in_version": "default",
@@ -656,7 +656,7 @@ diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/t
      "expires_in_version": "55",
      "kind": "enumerated",
      "keyed": true,
-@@ -8546,23 +8462,16 @@
+@@ -8513,23 +8429,16 @@
      "alert_emails": ["perf-telemetry-alerts@mozilla.com"],
      "expires_in_version": "never",
      "kind": "exponential",
@@ -680,7 +680,7 @@ diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/t
    },
    "SERVICE_WORKER_WAS_SPAWNED": {
      "record_in_processes": ["main", "content"],
-@@ -9073,25 +8982,16 @@
+@@ -9040,25 +8949,16 @@
    "WEBRTC_ICE_CHECKING_RATE": {
      "record_in_processes": ["main", "content"],
      "alert_emails": ["webrtc-ice-telemetry-alerts@mozilla.com"],
@@ -813,7 +813,7 @@ diff --git a/toolkit/components/telemetry/histogram-whitelists.json b/toolkit/co
      "PWMGR_MANAGE_COPIED_PASSWORD",
      "PWMGR_MANAGE_COPIED_USERNAME",
      "PWMGR_MANAGE_DELETED",
-@@ -1303,17 +1290,16 @@
+@@ -1301,17 +1288,16 @@
      "GEOLOCATION_ERROR",
      "JS_TELEMETRY_ADDON_EXCEPTIONS",
      "MASTER_PASSWORD_ENABLED",

+ 23 - 0
mozilla-release/patches/series

@@ -85,6 +85,7 @@ NOBUG-20170803-promisehelper-57a1.patch
 1402394-58a1.patch
 1402237-58a1.patch
 1392533-58a1.patch
+1403866-58a1.patch
 1305777-1-58a1.patch
 1305777-2-58a1.patch
 1305777-3-58a1.patch
@@ -510,6 +511,10 @@ NOBUG-20170803-promisehelper-57a1.patch
 1411565-59a1.patch
 1420233-59a1.patch
 1420303-59a1.patch
+1037335-1-59a1.patch
+1037335-2-59a1.patch
+1037335-3no4or5-59a1.patch
+1037335-6-59a1.patch
 1401942-1-59a1.patch
 1401942-2-59a1.patch
 1333140-2no1-59a1.patch
@@ -619,6 +624,7 @@ NOBUG-20170803-promisehelper-57a1.patch
 1405252-59a1.patch
 1408932-59a1.patch
 1425733-59a1.patch
+1425993-59a1.patch
 1426094-59a1.patch
 1426809-59a1.patch
 1419088-59a1.patch
@@ -632,6 +638,15 @@ NOBUG-20170803-promisehelper-57a1.patch
 1426194-1-59a1.patch
 1426194-2-59a1.patch
 1426057-59a1.patch
+1425574-1-59a1.patch
+1425574-2-59a1.patch
+1425574-3-59a1.patch
+1425574-4-59a1.patch
+1425574-5-59a1.patch
+1425574-6-59a1.patch
+1425574-7-59a1.patch
+1425574-8-59a1.patch
+1425574-9-59a1.patch
 1406038-59a1.patch
 1427184-59a1.patch
 1424722-59a1.patch
@@ -733,6 +748,8 @@ NOBUG-20170803-promisehelper-57a1.patch
 1405637-59a1.patch
 1430745-59a1.patch
 1430703-59a1.patch
+1418243-1no2-59a1.patch
+1418243-3-59a1.patch
 1422061-59a1.patch
 1404378-59a1.patch
 1431282-59a1.patch
@@ -2319,6 +2336,7 @@ servo-20170-60a1.patch
 1357688-60a1.patch
 1440497-60a1.patch
 1442037-60a1.patch
+1440816-1-60a1.patch
 1441779-1-60a1.patch
 1441779-2-60a1.patch
 1440169-1-60a1.patch
@@ -2519,6 +2537,7 @@ servo-20237-60a1.patch
 1436197-60a1.patch
 1440678-60a1.patch
 1444073-60a1.patch
+1440816-2-60a1.patch
 servo-20245-60a1.patch
 NOBUG-20180309-revendor-60a1.patch
 1434392-60a1.patch
@@ -2697,6 +2716,7 @@ NOBUG-20180313-compilefix-61a1.patch
 1431573-11-61a1.patch
 1431573-12-61a1.patch
 NOBUG-20180313-inspector-61a1.patch
+1443079-61a1.patch
 1445245-61a1.patch
 1441495-61a1.patch
 1443792-1-61a1.patch
@@ -2898,6 +2918,7 @@ servo-20351-61a1.patch
 1397795-2-61a1.patch
 1397795-3-61a1.patch
 1447262-61a1.patch
+1447422-61a1.patch
 1447632-61a1.patch
 1447157-61a1.patch
 1447326-61a1.patch
@@ -2952,6 +2973,8 @@ servo-20407-61a1.patch
 1448387-61a1.patch
 1440714-09-61a1.patch
 1445207-61a1.patch
+1447210-1-61a1.patch
+1447210-2-61a1.patch
 1447817-61a1.patch
 1431221-01-61a1.patch
 1431221-02-61a1.patch