From 2dd1aadeabdde8b15bb2c24bb0c850c3a2ab277d Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 16 Jun 2015 11:34:48 +1000 Subject: [PATCH] Bug 1171342 - Store contenteditable.css and designmode.css in the style sheet cache. r=jwatt --- dom/html/nsHTMLDocument.cpp | 60 +++++++----------------- layout/style/nsLayoutStylesheetCache.cpp | 28 +++++++++++ layout/style/nsLayoutStylesheetCache.h | 4 ++ 3 files changed, 49 insertions(+), 43 deletions(-) diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp index 786df0216d0..01e5d71eadb 100644 --- a/dom/html/nsHTMLDocument.cpp +++ b/dom/html/nsHTMLDocument.cpp @@ -113,6 +113,7 @@ #include "nsFocusManager.h" #include "nsIFrame.h" #include "nsIContent.h" +#include "nsLayoutStylesheetCache.h" using namespace mozilla; using namespace mozilla::dom; @@ -146,26 +147,6 @@ static bool ConvertToMidasInternalCommand(const nsAString & inCommandID, // ================================================================== // = // ================================================================== -static nsresult -RemoveFromAgentSheets(nsCOMArray &aAgentSheets, const nsAString& url) -{ - nsCOMPtr 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) @@ -2660,9 +2641,9 @@ nsHTMLDocument::TearingDownEditor(nsIEditor *aEditor) nsCOMArray 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); @@ -2800,41 +2781,34 @@ nsHTMLDocument::EditingStateChanged() rv = presShell->GetAgentStyleSheets(agentSheets); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr uri; - rv = NS_NewURI(getter_AddRefs(uri), - NS_LITERAL_STRING("resource://gre/res/contenteditable.css")); - NS_ENSURE_SUCCESS(rv, rv); + CSSStyleSheet* contentEditableSheet = + nsLayoutStylesheetCache::ContentEditableSheet(); - nsRefPtr sheet; - rv = LoadChromeSheetSync(uri, true, getter_AddRefs(sheet)); - NS_ENSURE_TRUE(sheet, rv); + bool result; - bool result = agentSheets.AppendObject(sheet); - NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY); + 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; } diff --git a/layout/style/nsLayoutStylesheetCache.cpp b/layout/style/nsLayoutStylesheetCache.cpp index 73f35aed0bb..d30dd0e1cca 100644 --- a/layout/style/nsLayoutStylesheetCache.cpp +++ b/layout/style/nsLayoutStylesheetCache.cpp @@ -244,6 +244,32 @@ nsLayoutStylesheetCache::ContentPreferenceSheet(nsPresContext* 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() { @@ -272,8 +298,10 @@ nsLayoutStylesheetCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf #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); diff --git a/layout/style/nsLayoutStylesheetCache.h b/layout/style/nsLayoutStylesheetCache.h index e3a0ddac403..15c55939db5 100644 --- a/layout/style/nsLayoutStylesheetCache.h +++ b/layout/style/nsLayoutStylesheetCache.h @@ -52,6 +52,8 @@ class nsLayoutStylesheetCache final 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(); @@ -85,8 +87,10 @@ private: static mozilla::StaticRefPtr gStyleCache; static mozilla::css::Loader* gCSSLoader; nsRefPtr mChromePreferenceSheet; + nsRefPtr mContentEditableSheet; nsRefPtr mContentPreferenceSheet; nsRefPtr mCounterStylesSheet; + nsRefPtr mDesignModeSheet; nsRefPtr mFormsSheet; nsRefPtr mFullScreenOverrideSheet; nsRefPtr mHTMLSheet;