Bug 1171342 - Store contenteditable.css and designmode.css in the style sheet cache. r=jwatt
authorCameron McCormack <cam@mcc.id.au>
Tue, 16 Jun 2015 11:34:48 +1000
changeset 249017 7ae3e54ebb633e8895ce987a5934613303360eaa
parent 249016 8f69f20370b7adbfc2ec2c608711369c36b6e3e5
child 249018 a4da65a36e31033a33d9945bdf36706373630360
push id28914
push usercbook@mozilla.com
push dateTue, 16 Jun 2015 14:11:13 +0000
treeherdermozilla-central@abaec2f7ed2c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs1171342
milestone41.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 1171342 - Store contenteditable.css and designmode.css in the style sheet cache. r=jwatt
dom/html/nsHTMLDocument.cpp
layout/style/nsLayoutStylesheetCache.cpp
layout/style/nsLayoutStylesheetCache.h
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -108,16 +108,17 @@
 #include "mozilla/dom/HTMLBodyElement.h"
 #include "mozilla/dom/HTMLDocumentBinding.h"
 #include "nsCharsetSource.h"
 #include "nsIStringBundle.h"
 #include "nsDOMClassInfo.h"
 #include "nsFocusManager.h"
 #include "nsIFrame.h"
 #include "nsIContent.h"
+#include "nsLayoutStylesheetCache.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 #define NS_MAX_DOCUMENT_WRITE_DEPTH 20
 
 #include "prtime.h"
 
@@ -141,36 +142,16 @@ static bool ConvertToMidasInternalComman
                                             bool& boolValue);
 
 static bool ConvertToMidasInternalCommand(const nsAString & inCommandID,
                                             nsACString& outCommandID);
 
 // ==================================================================
 // =
 // ==================================================================
-static nsresult
-RemoveFromAgentSheets(nsCOMArray<nsIStyleSheet> &aAgentSheets, const nsAString& url)
-{
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = NS_NewURI(getter_AddRefs(uri), url);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  for (int32_t i = aAgentSheets.Count() - 1; i >= 0; --i) {
-    nsIStyleSheet* sheet = aAgentSheets[i];
-    nsIURI* sheetURI = sheet->GetSheetURI();
-
-    bool equals = false;
-    uri->Equals(sheetURI, &equals);
-    if (equals) {
-      aAgentSheets.RemoveObjectAt(i);
-    }
-  }
-
-  return NS_OK;
-}
 
 nsresult
 NS_NewHTMLDocument(nsIDocument** aInstancePtrResult, bool aLoadedAsData)
 {
   nsRefPtr<nsHTMLDocument> doc = new nsHTMLDocument();
 
   nsresult rv = doc->Init();
 
@@ -2655,19 +2636,19 @@ nsHTMLDocument::TearingDownEditor(nsIEdi
 
     nsCOMPtr<nsIPresShell> presShell = GetShell();
     if (!presShell)
       return;
 
     nsCOMArray<nsIStyleSheet> agentSheets;
     presShell->GetAgentStyleSheets(agentSheets);
 
-    RemoveFromAgentSheets(agentSheets, NS_LITERAL_STRING("resource://gre/res/contenteditable.css"));
+    agentSheets.RemoveObject(nsLayoutStylesheetCache::ContentEditableSheet());
     if (oldState == eDesignMode)
-      RemoveFromAgentSheets(agentSheets, NS_LITERAL_STRING("resource://gre/res/designmode.css"));
+      agentSheets.RemoveObject(nsLayoutStylesheetCache::DesignModeSheet());
 
     presShell->SetAgentStyleSheets(agentSheets);
 
     presShell->ReconstructStyleData();
   }
 }
 
 nsresult
@@ -2795,51 +2776,44 @@ nsHTMLDocument::EditingStateChanged()
 
     // Before making this window editable, we need to modify UA style sheet
     // because new style may change whether focused element will be focusable
     // or not.
     nsCOMArray<nsIStyleSheet> agentSheets;
     rv = presShell->GetAgentStyleSheets(agentSheets);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsCOMPtr<nsIURI> uri;
-    rv = NS_NewURI(getter_AddRefs(uri),
-                   NS_LITERAL_STRING("resource://gre/res/contenteditable.css"));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsRefPtr<CSSStyleSheet> sheet;
-    rv = LoadChromeSheetSync(uri, true, getter_AddRefs(sheet));
-    NS_ENSURE_TRUE(sheet, rv);
-
-    bool result = agentSheets.AppendObject(sheet);
-    NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
+    CSSStyleSheet* contentEditableSheet =
+      nsLayoutStylesheetCache::ContentEditableSheet();
+
+    bool result;
+
+    if (!agentSheets.Contains(contentEditableSheet)) {
+      bool result = agentSheets.AppendObject(contentEditableSheet);
+      NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
+    }
 
     // Should we update the editable state of all the nodes in the document? We
     // need to do this when the designMode value changes, as that overrides
     // specific states on the elements.
     if (designMode) {
       // designMode is being turned on (overrides contentEditable).
-      rv = NS_NewURI(getter_AddRefs(uri),
-                     NS_LITERAL_STRING("resource://gre/res/designmode.css"));
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      rv = LoadChromeSheetSync(uri, true, getter_AddRefs(sheet));
-      NS_ENSURE_TRUE(sheet, rv);
-
-      result = agentSheets.AppendObject(sheet);
-      NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
+      CSSStyleSheet* designModeSheet =
+        nsLayoutStylesheetCache::DesignModeSheet();
+      if (!agentSheets.Contains(designModeSheet)) {
+        result = agentSheets.AppendObject(designModeSheet);
+        NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
+      }
 
       updateState = true;
       spellRecheckAll = oldState == eContentEditable;
     }
     else if (oldState == eDesignMode) {
       // designMode is being turned off (contentEditable is still on).
-      RemoveFromAgentSheets(agentSheets,
-        NS_LITERAL_STRING("resource://gre/res/designmode.css"));
-
+      agentSheets.RemoveObject(nsLayoutStylesheetCache::DesignModeSheet());
       updateState = true;
     }
 
     rv = presShell->SetAgentStyleSheets(agentSheets);
     NS_ENSURE_SUCCESS(rv, rv);
 
     presShell->ReconstructStyleData();
 
--- a/layout/style/nsLayoutStylesheetCache.cpp
+++ b/layout/style/nsLayoutStylesheetCache.cpp
@@ -239,16 +239,42 @@ nsLayoutStylesheetCache::ContentPreferen
   if (!gStyleCache->mContentPreferenceSheet) {
     gStyleCache->BuildPreferenceSheet(gStyleCache->mContentPreferenceSheet,
                                       aPresContext);
   }
 
   return gStyleCache->mContentPreferenceSheet;
 }
 
+/* static */ CSSStyleSheet*
+nsLayoutStylesheetCache::ContentEditableSheet()
+{
+  EnsureGlobal();
+
+  if (!gStyleCache->mContentEditableSheet) {
+    LoadSheetURL("resource://gre/res/contenteditable.css",
+                 gStyleCache->mContentEditableSheet, true);
+  }
+
+  return gStyleCache->mContentEditableSheet;
+}
+
+/* static */ CSSStyleSheet*
+nsLayoutStylesheetCache::DesignModeSheet()
+{
+  EnsureGlobal();
+
+  if (!gStyleCache->mDesignModeSheet) {
+    LoadSheetURL("resource://gre/res/designmode.css",
+                 gStyleCache->mDesignModeSheet, true);
+  }
+
+  return gStyleCache->mDesignModeSheet;
+}
+
 void
 nsLayoutStylesheetCache::Shutdown()
 {
   NS_IF_RELEASE(gCSSLoader);
   gStyleCache = nullptr;
 }
 
 MOZ_DEFINE_MALLOC_SIZE_OF(LayoutStylesheetCacheMallocSizeOf)
@@ -267,18 +293,20 @@ nsLayoutStylesheetCache::CollectReports(
 size_t
 nsLayoutStylesheetCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
   size_t n = aMallocSizeOf(this);
 
   #define MEASURE(s) n += s ? s->SizeOfIncludingThis(aMallocSizeOf) : 0;
 
   MEASURE(mChromePreferenceSheet);
+  MEASURE(mContentEditableSheet);
   MEASURE(mContentPreferenceSheet);
   MEASURE(mCounterStylesSheet);
+  MEASURE(mDesignModeSheet);
   MEASURE(mFormsSheet);
   MEASURE(mFullScreenOverrideSheet);
   MEASURE(mHTMLSheet);
   MEASURE(mMathMLSheet);
   MEASURE(mMinimalXULSheet);
   MEASURE(mNoFramesSheet);
   MEASURE(mNoScriptSheet);
   MEASURE(mNumberControlSheet);
--- a/layout/style/nsLayoutStylesheetCache.h
+++ b/layout/style/nsLayoutStylesheetCache.h
@@ -47,16 +47,18 @@ class nsLayoutStylesheetCache final
   static mozilla::CSSStyleSheet* FullScreenOverrideSheet();
   static mozilla::CSSStyleSheet* SVGSheet();
   static mozilla::CSSStyleSheet* MathMLSheet();
   static mozilla::CSSStyleSheet* CounterStylesSheet();
   static mozilla::CSSStyleSheet* NoScriptSheet();
   static mozilla::CSSStyleSheet* NoFramesSheet();
   static mozilla::CSSStyleSheet* ChromePreferenceSheet(nsPresContext* aPresContext);
   static mozilla::CSSStyleSheet* ContentPreferenceSheet(nsPresContext* aPresContext);
+  static mozilla::CSSStyleSheet* ContentEditableSheet();
+  static mozilla::CSSStyleSheet* DesignModeSheet();
 
   static void InvalidatePreferenceSheets();
 
   static void Shutdown();
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
 private:
@@ -80,18 +82,20 @@ private:
   static void AppendPreferenceRule(mozilla::CSSStyleSheet* aSheet,
                                    const nsAString& aRule);
   static void AppendPreferenceColorRule(mozilla::CSSStyleSheet* aSheet,
                                         const char* aString, nscolor aColor);
 
   static mozilla::StaticRefPtr<nsLayoutStylesheetCache> gStyleCache;
   static mozilla::css::Loader* gCSSLoader;
   nsRefPtr<mozilla::CSSStyleSheet> mChromePreferenceSheet;
+  nsRefPtr<mozilla::CSSStyleSheet> mContentEditableSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mContentPreferenceSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mCounterStylesSheet;
+  nsRefPtr<mozilla::CSSStyleSheet> mDesignModeSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mFormsSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mFullScreenOverrideSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mHTMLSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mMathMLSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mMinimalXULSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mNoFramesSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mNoScriptSheet;
   nsRefPtr<mozilla::CSSStyleSheet> mNumberControlSheet;