Bug 1013936, part 2 - Only load the html.css UA style sheet on-demand for SVG documents. r=bz CLOSED TREE

This commit is contained in:
Jonathan Watt 2014-05-24 20:29:11 +01:00
Родитель e07a2e6821
Коммит ec734706e6
12 изменённых файлов: 158 добавлений и 40 удалений

Просмотреть файл

@ -116,6 +116,7 @@ class NodeFilter;
class NodeIterator;
class ProcessingInstruction;
class StyleSheetList;
class SVGDocument;
class Touch;
class TouchList;
class TreeWalker;
@ -2289,6 +2290,7 @@ public:
uint32_t ChildElementCount();
virtual nsHTMLDocument* AsHTMLDocument() { return nullptr; }
virtual mozilla::dom::SVGDocument* AsSVGDocument() { return nullptr; }
virtual JSObject* WrapObject(JSContext *aCx) MOZ_OVERRIDE;

Просмотреть файл

@ -4005,6 +4005,10 @@ nsDocument::AddOnDemandBuiltInUASheet(nsCSSStyleSheet* aSheet)
// This is like |AddStyleSheetToStyleSets|, but for an agent sheet.
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
// Note that prepending here is necessary to make sure that html.css etc.
// do not override Firefox OS/Mobile's content.css sheet. Maybe we should
// have an insertion point to match the order of
// nsDocumentViewer::CreateStyleSet though?
shell->StyleSet()->PrependStyleSheet(nsStyleSet::eAgentSheet, aSheet);
}
}

Просмотреть файл

@ -6,6 +6,7 @@
#include "mozilla/ArrayUtils.h"
#include "nsCOMPtr.h"
#include "mozilla/dom/SVGDocument.h"
#include "mozilla/dom/SVGForeignObjectElement.h"
#include "mozilla/dom/SVGForeignObjectElementBinding.h"
@ -107,6 +108,31 @@ 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);
if (aDocument && aDocument->IsSVG()) {
// 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.
aDocument->AsSVGDocument()->EnsureNonSVGUserAgentStyleSheetsLoaded();
}
return rv;
}
NS_IMETHODIMP_(bool)
SVGForeignObjectElement::IsAttributeMapped(const nsIAtom* name) const
{

Просмотреть файл

@ -34,6 +34,9 @@ public:
virtual bool HasValidDimensions() const MOZ_OVERRIDE;
// nsIContent interface
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
bool aCompileEventHandlers) MOZ_OVERRIDE;
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;

Просмотреть файл

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/SVGDocument.h"
#include "nsLayoutStylesheetCache.h"
#include "nsString.h"
#include "nsLiteralString.h"
#include "nsIDOMSVGElement.h"
@ -68,6 +69,21 @@ SVGDocument::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
return CallQueryInterface(clone.get(), aResult);
}
void
SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded()
{
if (mHasLoadedNonSVGUserAgentStyleSheets) {
return;
}
mHasLoadedNonSVGUserAgentStyleSheets = true;
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::NumberControlSheet());
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::FormsSheet());
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::HTMLSheet());
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::UASheet());
}
JSObject*
SVGDocument::WrapNode(JSContext *aCx)
{

Просмотреть файл

@ -14,11 +14,16 @@ class nsSVGElement;
namespace mozilla {
namespace dom {
class SVGForeignObjectElement;
class SVGDocument MOZ_FINAL : public XMLDocument
{
friend class SVGForeignObjectElement; // To call EnsureNonSVGUserAgentStyleSheetsLoaded
public:
SVGDocument()
: XMLDocument("image/svg+xml")
, mHasLoadedNonSVGUserAgentStyleSheets(false)
{
mType = eSVG;
}
@ -29,8 +34,16 @@ public:
void GetDomain(nsAString& aDomain, ErrorResult& aRv);
nsSVGElement* GetRootElement(ErrorResult& aRv);
protected:
virtual SVGDocument* AsSVGDocument() MOZ_OVERRIDE {
return this;
}
private:
void EnsureNonSVGUserAgentStyleSheetsLoaded();
virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
bool mHasLoadedNonSVGUserAgentStyleSheets;
};
} // namespace dom

Просмотреть файл

@ -2250,52 +2250,77 @@ nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument,
}
}
sheet = nsLayoutStylesheetCache::NumberControlSheet();
if (sheet) {
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
}
sheet = nsLayoutStylesheetCache::FormsSheet();
if (sheet) {
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
}
sheet = nsLayoutStylesheetCache::FullScreenOverrideSheet();
if (sheet) {
styleSet->PrependStyleSheet(nsStyleSet::eOverrideSheet, sheet);
}
// Make sure to clone the quirk sheet so that it can be usefully
// enabled/disabled as needed.
nsRefPtr<nsCSSStyleSheet> quirkClone;
nsCSSStyleSheet* quirkSheet;
if (!nsLayoutStylesheetCache::UASheet() ||
!(quirkSheet = nsLayoutStylesheetCache::QuirkSheet()) ||
!(quirkClone = quirkSheet->Clone(nullptr, nullptr, nullptr, nullptr)) ||
!sheet) {
delete styleSet;
return NS_ERROR_OUT_OF_MEMORY;
}
// quirk.css needs to come after the regular UA sheet (or more precisely,
// after the html.css and so forth that the UA sheet imports).
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, quirkClone);
styleSet->SetQuirkStyleSheet(quirkClone);
if (aDocument->LoadsFullXULStyleSheetUpFront()) {
// nsXULElement::BindToTree loads xul.css on-demand if we don't load it
// up-front here.
sheet = nsLayoutStylesheetCache::XULSheet();
if (!aDocument->IsSVG()) {
// !!! IMPORTANT - KEEP THIS BLOCK IN SYNC WITH
// !!! SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded.
// 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 = nsLayoutStylesheetCache::NumberControlSheet();
if (sheet) {
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
}
sheet = nsLayoutStylesheetCache::FormsSheet();
if (sheet) {
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
}
// Make sure to clone the quirk sheet so that it can be usefully
// enabled/disabled as needed.
nsRefPtr<nsCSSStyleSheet> quirkClone;
nsCSSStyleSheet* quirkSheet;
if (!nsLayoutStylesheetCache::UASheet() ||
!(quirkSheet = nsLayoutStylesheetCache::QuirkSheet()) ||
!(quirkClone = quirkSheet->Clone(nullptr, nullptr, nullptr, nullptr)) ||
!sheet) {
delete styleSet;
return NS_ERROR_OUT_OF_MEMORY;
}
// quirk.css needs to come after the regular UA sheet (or more precisely,
// after the html.css and so forth that the UA sheet imports).
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, quirkClone);
styleSet->SetQuirkStyleSheet(quirkClone);
if (aDocument->LoadsFullXULStyleSheetUpFront()) {
// nsXULElement::BindToTree loads xul.css on-demand if we don't load it
// up-front here.
sheet = nsLayoutStylesheetCache::XULSheet();
if (sheet) {
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
}
}
sheet = nsLayoutStylesheetCache::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(nsStyleSet::eAgentSheet, sheet);
}
sheet = nsLayoutStylesheetCache::HTMLSheet();
if (sheet) {
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
}
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet,
nsLayoutStylesheetCache::UASheet());
} else {
// SVG documents may have scrollbars and need the scrollbar styling.
sheet = nsLayoutStylesheetCache::MinimalXULSheet();
if (sheet) {
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
}
}
sheet = nsLayoutStylesheetCache::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(nsStyleSet::eAgentSheet, sheet);
}
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet,
nsLayoutStylesheetCache::UASheet());
nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
if (sheetService) {

Просмотреть файл

@ -148,6 +148,16 @@ nsLayoutStylesheetCache::UASheet()
return gStyleCache->mUASheet;
}
nsCSSStyleSheet*
nsLayoutStylesheetCache::HTMLSheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
return gStyleCache->mHTMLSheet;
}
nsCSSStyleSheet*
nsLayoutStylesheetCache::MinimalXULSheet()
{
@ -250,6 +260,7 @@ nsLayoutStylesheetCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
MEASURE(mUserContentSheet);
MEASURE(mUserChromeSheet);
MEASURE(mUASheet);
MEASURE(mHTMLSheet);
MEASURE(mMinimalXULSheet);
MEASURE(mXULSheet);
MEASURE(mQuirkSheet);
@ -290,6 +301,12 @@ nsLayoutStylesheetCache::nsLayoutStylesheetCache()
}
NS_ASSERTION(mUASheet, "Could not load ua.css");
NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/html.css");
if (uri) {
LoadSheet(uri, mHTMLSheet, true);
}
NS_ASSERTION(mHTMLSheet, "Could not load xul.css");
NS_NewURI(getter_AddRefs(uri), "chrome://global/content/minimal-xul.css");
if (uri) {
LoadSheet(uri, mMinimalXULSheet, true);

Просмотреть файл

@ -39,6 +39,7 @@ class nsLayoutStylesheetCache MOZ_FINAL
static nsCSSStyleSheet* UserContentSheet();
static nsCSSStyleSheet* UserChromeSheet();
static nsCSSStyleSheet* UASheet();
static nsCSSStyleSheet* HTMLSheet();
static nsCSSStyleSheet* MinimalXULSheet();
static nsCSSStyleSheet* XULSheet();
static nsCSSStyleSheet* QuirkSheet();
@ -69,6 +70,7 @@ private:
nsRefPtr<nsCSSStyleSheet> mUserContentSheet;
nsRefPtr<nsCSSStyleSheet> mUserChromeSheet;
nsRefPtr<nsCSSStyleSheet> mUASheet;
nsRefPtr<nsCSSStyleSheet> mHTMLSheet;
nsRefPtr<nsCSSStyleSheet> mMinimalXULSheet;
nsRefPtr<nsCSSStyleSheet> mXULSheet;
nsRefPtr<nsCSSStyleSheet> mQuirkSheet;

Просмотреть файл

@ -632,6 +632,10 @@ nsStyleSet::EndUpdate()
void
nsStyleSet::EnableQuirkStyleSheet(bool aEnable)
{
if (!mQuirkStyleSheet) {
// SVG-as-an-image doesn't load this sheet
return;
}
#ifdef DEBUG
bool oldEnabled;
{

Просмотреть файл

@ -2,8 +2,6 @@
* 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/. */
@import url(resource://gre-resources/html.css);
@namespace parsererror url(http://www.mozilla.org/newlayout/xml/parsererror.xml);
@namespace xul url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);

Просмотреть файл

@ -74,3 +74,11 @@ foreignObject {
mask: inherit;
opacity: inherit;
}
/* nsDocumentViewer::CreateStyleSet doesn't load ua.css for SVG-as-an-image,
* but SVG-as-an-image needs this rule from that file.
*/
*|*::-moz-viewport, *|*::-moz-viewport-scroll, *|*::-moz-canvas, *|*::-moz-scrolled-canvas {
display: block !important;
background-color: inherit;
}