зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1468133: Remove the optimization to lazily load non-SVG styles since it's not relevant anymore. r=heycam
This was a memory-saving optimization introduced as part of dependencies for bug 686875, but a more general system landed in bug 77999 for Gecko and https://github.com/servo/servo/pull/18509 for Servo. So now it's probably even a bit of a pessimization (though probably not huge), and given this causes bugs like bug 1462742, bug 1157592, and bug 1468145, and fishiness like the one pointed out in this bug, we may as well remove it. The performance impact of having to lookup through more rules should be minimal given the bloom filter and the rule hash optimizations. This makes me wonder whether we could remove the whole concept of on-demand UA sheets, since they've caused pain, for example, when the frontend people try loading <svg>s from NAC (since that triggers sheet loading from frame construction, which is not good). I'm not concerned about loading mathml.css and svg.css everywhere, though xul.css may not be as doable since it adds a bunch of attribute-dependent selectors. Though on the other hand I asserted in the xul.css code and we don't load it in content with <video> / <input type="date/time/etc"> and such, afaict, so maybe now that legacy addons are gone we can remove that sheet from content processes altogether. MozReview-Commit-ID: 9JCWNZj6BkT
This commit is contained in:
Родитель
3d4fb99408
Коммит
bd7c1e4e8c
|
@ -5358,12 +5358,6 @@ nsIDocument::InsertAnonymousContent(Element& aElement, ErrorResult& aRv)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// We're about to insert random content here that will be rendered. We're
|
||||
// going to need more than svg.css here...
|
||||
if (IsSVGDocument()) {
|
||||
AsSVGDocument()->EnsureNonSVGUserAgentStyleSheetsLoaded();
|
||||
}
|
||||
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
nsCOMPtr<Element> container = shell->GetCanvasFrame()
|
||||
->GetCustomContentContainer();
|
||||
|
|
|
@ -2017,7 +2017,13 @@ public:
|
|||
}
|
||||
bool LoadsFullXULStyleSheetUpFront()
|
||||
{
|
||||
return IsXULDocument() || AllowXULXBL();
|
||||
if (IsXULDocument()) {
|
||||
return true;
|
||||
}
|
||||
if (IsSVGDocument()) {
|
||||
return false;
|
||||
}
|
||||
return AllowXULXBL();
|
||||
}
|
||||
|
||||
bool IsScriptEnabled();
|
||||
|
|
|
@ -30,26 +30,6 @@ namespace dom {
|
|||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISupports methods:
|
||||
|
||||
nsresult
|
||||
SVGDocument::InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
|
||||
bool aNotify)
|
||||
{
|
||||
if (aKid->IsElement() && !aKid->IsSVGElement()) {
|
||||
// We can get here when well formed XML with a non-SVG root element is
|
||||
// served with the SVG MIME type, for example. In that case we need to load
|
||||
// the non-SVG UA sheets or else we can get bugs like bug 1016145. Note
|
||||
// that we have to do this _before_ the XMLDocument::InsertChildBefore,
|
||||
// since that can try to construct frames, and we need to have the sheets
|
||||
// loaded by then.
|
||||
EnsureNonSVGUserAgentStyleSheetsLoaded();
|
||||
}
|
||||
|
||||
return XMLDocument::InsertChildBefore(aKid, aBeforeThis, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
SVGDocument::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
|
||||
bool aPreallocateChildren) const
|
||||
|
@ -64,97 +44,6 @@ SVGDocument::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
|
|||
return CallQueryInterface(clone.get(), aResult);
|
||||
}
|
||||
|
||||
void
|
||||
SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded()
|
||||
{
|
||||
if (mHasLoadedNonSVGUserAgentStyleSheets) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsStaticDocument()) {
|
||||
// If we're a static clone of a document, then
|
||||
// nsIDocument::CreateStaticClone will handle cloning the original
|
||||
// document's sheets, including the on-demand non-SVG UA sheets,
|
||||
// for us.
|
||||
return;
|
||||
}
|
||||
|
||||
mHasLoadedNonSVGUserAgentStyleSheets = true;
|
||||
|
||||
if (IsBeingUsedAsImage()) {
|
||||
// nsDocumentViewer::CreateStyleSet skipped loading all user-agent/user
|
||||
// style sheets in this case, but we'll need B2G/Fennec'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 the other sheets below because
|
||||
// EnsureOnDemandBuiltInUASheet prepends, and B2G/Fennec's/GeckoView's
|
||||
// content.css must come after those UASheet() etc.
|
||||
//
|
||||
// FIXME(emilio, bug 1468133): We may already have loaded some of the other
|
||||
// on-demand built-in UA sheets, including svg.css, so this looks somewhat
|
||||
// bogus... Also, this should probably just use the stylesheet service which
|
||||
// also has the right sheets cached and parsed here...
|
||||
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);
|
||||
|
||||
nsCString 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) {
|
||||
RefPtr<StyleSheet> sheet;
|
||||
cssLoader->LoadSheetSync(uri,
|
||||
mozilla::css::eAgentSheetFeatures,
|
||||
true, &sheet);
|
||||
if (sheet) {
|
||||
EnsureOnDemandBuiltInUASheet(sheet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto cache = nsLayoutStylesheetCache::Singleton();
|
||||
|
||||
EnsureOnDemandBuiltInUASheet(cache->FormsSheet());
|
||||
EnsureOnDemandBuiltInUASheet(cache->CounterStylesSheet());
|
||||
EnsureOnDemandBuiltInUASheet(cache->HTMLSheet());
|
||||
if (nsLayoutUtils::ShouldUseNoFramesSheet(this)) {
|
||||
EnsureOnDemandBuiltInUASheet(cache->NoFramesSheet());
|
||||
}
|
||||
if (nsLayoutUtils::ShouldUseNoScriptSheet(this)) {
|
||||
EnsureOnDemandBuiltInUASheet(cache->NoScriptSheet());
|
||||
}
|
||||
EnsureOnDemandBuiltInUASheet(cache->UASheet());
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -22,19 +22,13 @@ class SVGForeignObjectElement;
|
|||
|
||||
class SVGDocument final : public XMLDocument
|
||||
{
|
||||
friend class SVGForeignObjectElement; // To call EnsureNonSVGUserAgentStyleSheetsLoaded
|
||||
friend class nsIDocument; // Same reason.
|
||||
|
||||
public:
|
||||
SVGDocument()
|
||||
: XMLDocument("image/svg+xml")
|
||||
, mHasLoadedNonSVGUserAgentStyleSheets(false)
|
||||
{
|
||||
mType = eSVG;
|
||||
}
|
||||
|
||||
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
|
||||
bool aNotify) override;
|
||||
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
|
||||
bool aPreallocateChildren) const override;
|
||||
|
||||
|
@ -49,9 +43,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void EnsureNonSVGUserAgentStyleSheetsLoaded();
|
||||
|
||||
bool mHasLoadedNonSVGUserAgentStyleSheets;
|
||||
|
||||
// This is maintained by AutoSetRestoreSVGContextPaint.
|
||||
const SVGContextPaint* mCurrentContextPaint = nullptr;
|
||||
|
|
|
@ -107,32 +107,6 @@ SVGForeignObjectElement::HasValidDimensions() const
|
|||
//----------------------------------------------------------------------
|
||||
// nsIContent methods
|
||||
|
||||
nsresult
|
||||
SVGForeignObjectElement::BindToTree(nsIDocument* aDocument,
|
||||
nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers)
|
||||
{
|
||||
nsresult rv = SVGGraphicsElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsIDocument* doc = GetComposedDoc();
|
||||
if (doc && doc->IsSVGDocument()) {
|
||||
// We assume that we're going to have HTML content, so we ensure that the
|
||||
// UA style sheets that nsDocumentViewer::CreateStyleSet skipped when
|
||||
// it saw the document was an SVG document are loaded.
|
||||
//
|
||||
// We setup these style sheets during binding, not element construction,
|
||||
// because elements can be moved from the document that creates them to
|
||||
// another document.
|
||||
doc->AsSVGDocument()->EnsureNonSVGUserAgentStyleSheetsLoaded();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
SVGForeignObjectElement::IsAttributeMapped(const nsAtom* name) const
|
||||
{
|
||||
|
|
|
@ -36,9 +36,6 @@ public:
|
|||
virtual bool HasValidDimensions() const override;
|
||||
|
||||
// nsIContent interface
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers) override;
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* name) const override;
|
||||
|
||||
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
|
||||
|
|
|
@ -495,11 +495,10 @@ SVGSVGElement::BindToTree(nsIDocument* aDocument,
|
|||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsIDocument* doc = GetComposedDoc();
|
||||
if (doc) {
|
||||
// Setup the style sheet during binding, not element construction,
|
||||
// because we could move the root SVG element from the document
|
||||
// that created it to another document.
|
||||
if (nsIDocument* doc = GetComposedDoc()) {
|
||||
// Setup the style sheet during binding, not element construction, because
|
||||
// we could move the root SVG element from the document that created it to
|
||||
// another document.
|
||||
auto cache = nsLayoutStylesheetCache::Singleton();
|
||||
doc->EnsureOnDemandBuiltInUASheet(cache->SVGSheet());
|
||||
}
|
||||
|
|
|
@ -765,10 +765,7 @@ nsXULElement::BindToTree(nsIDocument* aDocument,
|
|||
|
||||
nsIDocument* doc = GetComposedDoc();
|
||||
#ifdef DEBUG
|
||||
if (doc &&
|
||||
!doc->LoadsFullXULStyleSheetUpFront() &&
|
||||
!doc->IsUnstyledDocument()) {
|
||||
|
||||
if (doc && !doc->AllowXULXBL() && !doc->IsUnstyledDocument()) {
|
||||
// To save CPU cycles and memory, non-XUL documents only load the user
|
||||
// agent style sheet rules for a minimal set of XUL elements such as
|
||||
// 'scrollbar' that may be created implicitly for their content (those
|
||||
|
|
|
@ -2440,19 +2440,6 @@ nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument)
|
|||
UniquePtr<ServoStyleSet> styleSet = MakeUnique<ServoStyleSet>();
|
||||
|
||||
// The document will fill in the document sheets when we create the presshell
|
||||
|
||||
if (aDocument->IsBeingUsedAsImage()) {
|
||||
MOZ_ASSERT(aDocument->IsSVGDocument(),
|
||||
"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!
|
||||
return styleSet;
|
||||
}
|
||||
|
||||
auto cache = nsLayoutStylesheetCache::Singleton();
|
||||
|
||||
// Handle the user sheets.
|
||||
|
@ -2473,81 +2460,63 @@ nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument)
|
|||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
|
||||
if (!aDocument->IsSVGDocument()) {
|
||||
// !!! IMPORTANT - KEEP THIS BLOCK IN SYNC WITH
|
||||
// !!! SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded.
|
||||
sheet = cache->FormsSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
|
||||
// SVGForeignObjectElement::BindToTree calls SVGDocument::
|
||||
// EnsureNonSVGUserAgentStyleSheetsLoaded to loads these UA sheet
|
||||
// on-demand. (Excluding the quirks sheet, which should never be loaded for
|
||||
// an SVG document, and excluding xul.css which will be loaded on demand by
|
||||
// nsXULElement::BindToTree.)
|
||||
|
||||
sheet = cache->FormsSheet();
|
||||
if (aDocument->LoadsFullXULStyleSheetUpFront()) {
|
||||
// This is the only place components.css gets loaded, unlike xul.css
|
||||
sheet = cache->XULComponentsSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
|
||||
if (aDocument->LoadsFullXULStyleSheetUpFront()) {
|
||||
// This is the only place components.css gets loaded, unlike xul.css
|
||||
sheet = cache->XULComponentsSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
|
||||
// nsXULElement::BindToTree loads xul.css on-demand if we don't load it
|
||||
// up-front here.
|
||||
sheet = cache->XULSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
}
|
||||
|
||||
sheet = cache->MinimalXULSheet();
|
||||
if (sheet) {
|
||||
// Load the minimal XUL rules for scrollbars and a few other XUL things
|
||||
// that non-XUL (typically HTML) documents commonly use.
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
|
||||
sheet = cache->CounterStylesSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
|
||||
if (nsLayoutUtils::ShouldUseNoScriptSheet(aDocument)) {
|
||||
sheet = cache->NoScriptSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
}
|
||||
|
||||
if (nsLayoutUtils::ShouldUseNoFramesSheet(aDocument)) {
|
||||
sheet = cache->NoFramesSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
}
|
||||
|
||||
// We don't add quirk.css here; nsPresContext::CompatibilityModeChanged will
|
||||
// append it if needed.
|
||||
|
||||
sheet = cache->HTMLSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, cache->UASheet());
|
||||
} else {
|
||||
// SVG documents may have scrollbars and need the scrollbar styling.
|
||||
sheet = cache->MinimalXULSheet();
|
||||
// nsXULElement::BindToTree loads xul.css on-demand if we don't load it
|
||||
// up-front here.
|
||||
sheet = cache->XULSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
}
|
||||
|
||||
nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance();
|
||||
if (sheetService) {
|
||||
sheet = cache->MinimalXULSheet();
|
||||
if (sheet) {
|
||||
// Load the minimal XUL rules for scrollbars and a few other XUL things
|
||||
// that non-XUL (typically HTML) documents commonly use.
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
|
||||
sheet = cache->CounterStylesSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
|
||||
if (nsLayoutUtils::ShouldUseNoScriptSheet(aDocument)) {
|
||||
sheet = cache->NoScriptSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
}
|
||||
|
||||
if (nsLayoutUtils::ShouldUseNoFramesSheet(aDocument)) {
|
||||
sheet = cache->NoFramesSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
}
|
||||
|
||||
// We don't add quirk.css here; nsPresContext::CompatibilityModeChanged will
|
||||
// append it if needed.
|
||||
|
||||
sheet = cache->HTMLSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, cache->UASheet());
|
||||
|
||||
if (nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance()) {
|
||||
for (StyleSheet* sheet : *sheetService->AgentStyleSheets()) {
|
||||
styleSet->AppendStyleSheet(SheetType::Agent, sheet);
|
||||
}
|
||||
|
|
|
@ -2344,13 +2344,6 @@ nsPrintJob::ReflowPrintObject(const UniquePtr<nsPrintObject>& aPO)
|
|||
UniquePtr<ServoStyleSet> styleSet =
|
||||
mDocViewerPrint->CreateStyleSet(aPO->mDocument);
|
||||
|
||||
if (aPO->mDocument->IsSVGDocument()) {
|
||||
// The SVG document only loads minimal-xul.css, so it doesn't apply other
|
||||
// styles. We should add ua.css for applying style which related to print.
|
||||
auto cache = nsLayoutStylesheetCache::Singleton();
|
||||
styleSet->PrependStyleSheet(SheetType::Agent, cache->UASheet());
|
||||
}
|
||||
|
||||
aPO->mPresShell = aPO->mDocument->CreateShell(aPO->mPresContext,
|
||||
aPO->mViewManager,
|
||||
std::move(styleSet));
|
||||
|
|
|
@ -84,27 +84,3 @@ foreignObject {
|
|||
/* Don't specify the outline-color, we should always use initial value. */
|
||||
outline: 1px dotted;
|
||||
}
|
||||
|
||||
/* nsDocumentViewer::CreateStyleSet doesn't load ua.css.
|
||||
* A few styles are common to html and SVG though
|
||||
* so we copy the rules below from that file.
|
||||
*/
|
||||
|
||||
/* Links */
|
||||
|
||||
*|*:any-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
*|*:any-link:-moz-focusring {
|
||||
/* Don't specify the outline-color, we should always use initial value. */
|
||||
outline: 1px dotted;
|
||||
}
|
||||
|
||||
/*
|
||||
* SVG-as-an-image needs this rule
|
||||
*/
|
||||
*|*::-moz-viewport, *|*::-moz-viewport-scroll, *|*::-moz-canvas, *|*::-moz-scrolled-canvas {
|
||||
display: block !important;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче