Bug 1011806 - Stop loading user-agent and user style sheets for SVG-as-an-image (the main UA sheets svg.css, html.css, etc. will still load on demand). r=bz CLOSED TREE

This commit is contained in:
Jonathan Watt 2014-05-24 21:37:48 +01:00
parent 2783feef5b
commit 994403b30e
3 changed files with 81 additions and 1 deletions

View File

@ -4,7 +4,15 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/SVGDocument.h"
#include "mozilla/css/Loader.h"
#include "nsICategoryManager.h"
#include "nsISimpleEnumerator.h"
#include "nsIStyleSheetService.h"
#include "nsISupportsPrimitives.h"
#include "nsLayoutStylesheetCache.h"
#include "nsNetUtil.h"
#include "nsServiceManagerUtils.h"
#include "nsString.h"
#include "nsLiteralString.h"
#include "nsIDOMSVGElement.h"
@ -12,6 +20,7 @@
#include "nsSVGElement.h"
#include "mozilla/dom/SVGDocumentBinding.h"
using namespace mozilla::css;
using namespace mozilla::dom;
namespace mozilla {
@ -78,6 +87,59 @@ SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded()
mHasLoadedNonSVGUserAgentStyleSheets = true;
if (IsBeingUsedAsImage()) {
// nsDocumentViewer::CreateStyleSet skipped loading all user-agent/user
// style sheets in this case, but we'll need B2G/Fennec/Metro's
// content.css. We could load all the sheets registered with the
// nsIStyleSheetService (and maybe we should) but most likely it isn't
// desirable or necessary for foreignObject in SVG-as-an-image. Instead we
// only load the "agent-style-sheets" that nsStyleSheetService::Init()
// pulls in from the category manager. That keeps memory use of
// SVG-as-an-image down.
//
// We do this before adding UASheet() etc. below because
// EnsureOnDemandBuiltInUASheet prepends, and B2G/Fennec/Metro's
// content.css must come after UASheet() etc.
nsCOMPtr<nsICategoryManager> catMan =
do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
if (catMan) {
nsCOMPtr<nsISimpleEnumerator> sheets;
catMan->EnumerateCategory("agent-style-sheets", getter_AddRefs(sheets));
if (sheets) {
bool hasMore;
while (NS_SUCCEEDED(sheets->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> sheet;
if (NS_FAILED(sheets->GetNext(getter_AddRefs(sheet))))
break;
nsCOMPtr<nsISupportsCString> icStr = do_QueryInterface(sheet);
MOZ_ASSERT(icStr,
"category manager entries must be nsISupportsCStrings");
nsAutoCString name;
icStr->GetData(name);
nsXPIDLCString spec;
catMan->GetCategoryEntry("agent-style-sheets", name.get(),
getter_Copies(spec));
mozilla::css::Loader* cssLoader = CSSLoader();
if (cssLoader->GetEnabled()) {
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), spec);
if (uri) {
nsRefPtr<nsCSSStyleSheet> cssSheet;
cssLoader->LoadSheetSync(uri, true, true, getter_AddRefs(cssSheet));
if (cssSheet) {
EnsureOnDemandBuiltInUASheet(cssSheet);
}
}
}
}
}
}
}
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::NumberControlSheet());
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::FormsSheet());
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::HTMLSheet());

View File

@ -2188,7 +2188,22 @@ nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument,
styleSet->BeginUpdate();
// The document will fill in the document sheets when we create the presshell
if (aDocument->IsBeingUsedAsImage()) {
MOZ_ASSERT(aDocument->IsSVG(),
"Do we want to skip most sheets for this new image type?");
// SVG-as-an-image must be kept as light and small as possible. We
// deliberately skip loading everything and leave svg.css (and html.css and
// xul.css) to be loaded on-demand.
// XXXjwatt Nothing else is loaded on-demand, but I don't think that
// should matter for SVG-as-an-image. If it does, I want to know why!
// Caller will handle calling EndUpdate, per contract.
*aStyleSet = styleSet;
return NS_OK;
}
// Handle the user sheets.
nsCSSStyleSheet* sheet = nullptr;
if (nsContentUtils::IsInChromeDocshell(aDocument)) {

View File

@ -97,6 +97,9 @@ nsStyleSheetService::FindSheetByURI(const nsCOMArray<nsIStyleSheet> &sheets,
nsresult
nsStyleSheetService::Init()
{
// If you make changes here, consider whether
// SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded should be updated too.
// Child processes get their style sheets from the ContentParent.
if (XRE_GetProcessType() == GeckoProcessType_Content) {
return NS_OK;