Bug 1452143: Expose and honor a cssErrorReportingEnabled in the docshell. r=bholley
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 12 Apr 2018 11:59:09 +0200
changeset 414078 3f214ca585db301f1c1f284b9a63dd5c98c15f8b
parent 414077 d46b75deaae586798e885c3e61f8efb0bfdb3069
child 414079 8c85b98829b26bf386ab01b60ce3ae3e565d2ed0
push id33858
push userncsoregi@mozilla.com
push dateTue, 17 Apr 2018 21:55:44 +0000
treeherdermozilla-central@d6eb5597d744 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1452143
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1452143: Expose and honor a cssErrorReportingEnabled in the docshell. r=bholley The idea would be for parallel CSS parsing to check the static methods in ErrorReporter before loading the sheet. MozReview-Commit-ID: D7cedJQpz9K
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/nsIDocShell.idl
layout/style/ErrorReporter.cpp
layout/style/ErrorReporter.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -357,16 +357,17 @@ nsDocShell::nsDocShell()
   , mAllowImages(true)
   , mAllowMedia(true)
   , mAllowDNSPrefetch(true)
   , mAllowWindowControl(true)
   , mAllowContentRetargeting(true)
   , mAllowContentRetargetingOnChildren(true)
   , mUseErrorPages(false)
   , mObserveErrorPages(true)
+  , mCSSErrorReportingEnabled(false)
   , mAllowAuth(true)
   , mAllowKeywordFixup(false)
   , mIsOffScreenBrowser(false)
   , mIsActive(true)
   , mDisableMetaRefreshWhenInactive(false)
   , mIsAppTab(false)
   , mUseGlobalHistory(false)
   , mUseRemoteTabs(false)
@@ -1682,16 +1683,31 @@ nsDocShell::GetAllowJavascript(bool* aAl
 {
   NS_ENSURE_ARG_POINTER(aAllowJavascript);
 
   *aAllowJavascript = mAllowJavascript;
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsDocShell::GetCssErrorReportingEnabled(bool* aEnabled)
+{
+  MOZ_ASSERT(aEnabled);
+  *aEnabled = mCSSErrorReportingEnabled;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShell::SetCssErrorReportingEnabled(bool aEnabled)
+{
+  mCSSErrorReportingEnabled = aEnabled;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsDocShell::SetAllowJavascript(bool aAllowJavascript)
 {
   mAllowJavascript = aAllowJavascript;
   RecomputeCanExecuteScripts();
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -885,16 +885,21 @@ private: // member functions
 
   already_AddRefed<mozilla::dom::ChildSHistory> GetRootSessionHistory();
 
   inline bool UseErrorPages()
   {
     return (mObserveErrorPages ? sUseErrorPages : mUseErrorPages);
   }
 
+  bool CSSErrorReportingEnabled() const
+  {
+    return mCSSErrorReportingEnabled;
+  }
+
 private: // data members
   static nsIURIFixup* sURIFixup;
 
   // Cached value of the "browser.xul.error_pages.enabled" preference.
   static bool sUseErrorPages;
 
 #ifdef DEBUG
   // We're counting the number of |nsDocShells| to help find leaks
@@ -1103,16 +1108,17 @@ private: // data members
   bool mAllowImages : 1;
   bool mAllowMedia : 1;
   bool mAllowDNSPrefetch : 1;
   bool mAllowWindowControl : 1;
   bool mAllowContentRetargeting : 1;
   bool mAllowContentRetargetingOnChildren : 1;
   bool mUseErrorPages : 1;
   bool mObserveErrorPages : 1;
+  bool mCSSErrorReportingEnabled : 1;
   bool mAllowAuth : 1;
   bool mAllowKeywordFixup : 1;
   bool mIsOffScreenBrowser : 1;
   bool mIsActive : 1;
   bool mDisableMetaRefreshWhenInactive : 1;
   bool mIsAppTab : 1;
   bool mUseGlobalHistory : 1;
   bool mUseRemoteTabs : 1;
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -284,21 +284,26 @@ interface nsIDocShell : nsIDocShellTreeI
 
   /**
    * This attribute allows chrome to tie in to handle DOM events that may
    * be of interest to chrome.
    */
   attribute nsIDOMEventTarget chromeEventHandler;
 
   /**
-    * This allows chrome to set a custom User agent on a specific docshell
-    */
+   * This allows chrome to set a custom User agent on a specific docshell
+   */
   attribute DOMString customUserAgent;
 
   /**
+   * Whether CSS error reporting is enabled.
+   */
+  attribute boolean cssErrorReportingEnabled;
+
+  /**
    * Whether to allow plugin execution
    */
   attribute boolean allowPlugins;
 
   /**
    * Whether to allow Javascript execution
    */
   attribute boolean allowJavascript;
--- a/layout/style/ErrorReporter.cpp
+++ b/layout/style/ErrorReporter.cpp
@@ -11,17 +11,19 @@
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/css/Loader.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/SystemGroup.h"
 #include "nsCSSScanner.h"
 #include "nsIConsoleService.h"
 #include "nsIDocument.h"
+#include "nsIDocShell.h"
 #include "nsIFactory.h"
+#include "nsINode.h"
 #include "nsIScriptError.h"
 #include "nsISensitiveInfoHiddenURI.h"
 #include "nsIStringBundle.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStyleUtil.h"
 #include "nsThreadUtils.h"
 #include "nsNetUtil.h"
 
@@ -129,19 +131,21 @@ ErrorReporter::ReleaseGlobals()
   NS_IF_RELEASE(sSpecCache);
 }
 
 ErrorReporter::ErrorReporter(const StyleSheet* aSheet,
                              const Loader* aLoader,
                              nsIURI* aURI)
   : mSheet(aSheet)
   , mLoader(aLoader)
-  , mURI(aURI),
-    mInnerWindowID(0), mErrorLineNumber(0), mPrevErrorLineNumber(0),
-    mErrorColNumber(0)
+  , mURI(aURI)
+  , mInnerWindowID(0)
+  , mErrorLineNumber(0)
+  , mPrevErrorLineNumber(0)
+  , mErrorColNumber(0)
 {
 }
 
 ErrorReporter::~ErrorReporter()
 {
   // Schedule deferred cleanup for cached data. We want to strike a
   // balance between performance and memory usage, so we only allow
   // short-term caching.
@@ -153,16 +157,64 @@ ErrorReporter::~ErrorReporter()
       // Peform the "deferred" cleanup immediately if the dispatch fails.
       sSpecCache->Run();
     } else {
       sSpecCache->SetPending();
     }
   }
 }
 
+bool
+ErrorReporter::ShouldReportErrors(const nsIDocument& aDoc)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  nsIDocShell* shell = aDoc.GetDocShell();
+  if (!shell) {
+    return false;
+  }
+
+  bool report = false;
+  shell->GetCssErrorReportingEnabled(&report);
+  return report;
+}
+
+bool
+ErrorReporter::ShouldReportErrors()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  EnsureGlobalsInitialized();
+  if (!sReportErrors) {
+    return false;
+  }
+
+  if (mInnerWindowID) {
+    // We already reported an error, and that has cleared mSheet and mLoader, so
+    // we'd get the bogus value otherwise.
+    return true;
+  }
+
+  if (mSheet) {
+    nsINode* owner = mSheet->GetOwnerNode()
+      ? mSheet->GetOwnerNode()
+      : mSheet->GetAssociatedDocument();
+
+    if (owner && ShouldReportErrors(*owner->OwnerDoc())) {
+      return true;
+    }
+  }
+
+  if (mLoader && mLoader->GetDocument() &&
+      ShouldReportErrors(*mLoader->GetDocument())) {
+    return true;
+  }
+
+  return false;
+}
+
 void
 ErrorReporter::OutputError()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(ShouldReportErrors());
 
   if (mError.IsEmpty()) {
     return;
@@ -253,41 +305,41 @@ void
 ErrorReporter::ClearError()
 {
   mError.Truncate();
 }
 
 void
 ErrorReporter::AddToError(const nsString &aErrorText)
 {
-  if (!ShouldReportErrors()) return;
+  MOZ_ASSERT(ShouldReportErrors());
 
   if (mError.IsEmpty()) {
     mError = aErrorText;
   } else {
     mError.AppendLiteral("  ");
     mError.Append(aErrorText);
   }
 }
 
 void
 ErrorReporter::ReportUnexpected(const char *aMessage)
 {
-  if (!ShouldReportErrors()) return;
+  MOZ_ASSERT(ShouldReportErrors());
 
   nsAutoString str;
   sStringBundle->GetStringFromName(aMessage, str);
   AddToError(str);
 }
 
 void
 ErrorReporter::ReportUnexpectedUnescaped(const char *aMessage,
                                          const nsAutoString& aParam)
 {
-  if (!ShouldReportErrors()) return;
+  MOZ_ASSERT(ShouldReportErrors());
 
   const char16_t *params[1] = { aParam.get() };
 
   nsAutoString str;
   sStringBundle->FormatStringFromName(aMessage, params, ArrayLength(params),
                                       str);
   AddToError(str);
 }
--- a/layout/style/ErrorReporter.h
+++ b/layout/style/ErrorReporter.h
@@ -4,23 +4,23 @@
  * 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/. */
 
 /* diagnostic reporting for CSS style sheet parser */
 
 #ifndef mozilla_css_ErrorReporter_h_
 #define mozilla_css_ErrorReporter_h_
 
-#include "nsString.h"
+#include "nsStringFwd.h"
 
 struct nsCSSToken;
+class nsIDocument;
 class nsIURI;
 
 namespace mozilla {
-class ServoStyleSheet;
 class StyleSheet;
 
 namespace css {
 
 class Loader;
 
 class ErrorReporter {
 public:
@@ -32,50 +32,48 @@ public:
   static void ReleaseGlobals();
   static void EnsureGlobalsInitialized()
   {
     if (MOZ_UNLIKELY(!sInitialized)) {
       InitGlobals();
     }
   }
 
-  bool ShouldReportErrors() const
-  {
-    EnsureGlobalsInitialized();
-    return sReportErrors;
-  }
+  static bool ShouldReportErrors(const nsIDocument&);
+
+  bool ShouldReportErrors();
 
   void OutputError(uint32_t aLineNumber,
                    uint32_t aLineOffset,
                    const nsACString& aSource);
   void ClearError();
 
   // In all overloads of ReportUnexpected, aMessage is a stringbundle
   // name, which will be processed as a format string with the
   // indicated number of parameters.
 
   // no parameters
   void ReportUnexpected(const char *aMessage);
   // one parameter which has already been escaped appropriately
-  void ReportUnexpectedUnescaped(const char *aMessage,
+  void ReportUnexpectedUnescaped(const char* aMessage,
                                  const nsAutoString& aParam);
 
 private:
   void OutputError();
   void AddToError(const nsString &aErrorText);
   static void InitGlobals();
 
   static bool sInitialized;
   static bool sReportErrors;
 
   nsAutoString mError;
   nsString mErrorLine;
   nsString mFileName;
-  const StyleSheet *mSheet;
-  const Loader *mLoader;
+  const StyleSheet* mSheet;
+  const Loader* mLoader;
   nsIURI *mURI;
   uint64_t mInnerWindowID;
   uint32_t mErrorLineNumber;
   uint32_t mPrevErrorLineNumber;
   uint32_t mErrorColNumber;
 };
 
 } // namespace css