Bug 1014891 - Remove support for XML's 'catalog' style sheets, and provide an internal alternative for the abusing callers of EnsureCatalogStyleSheet. r=bz

This commit is contained in:
Jonathan Watt 2014-05-24 19:46:38 +01:00
parent 6251343995
commit fd3a1b8954
8 changed files with 117 additions and 133 deletions

View File

@ -133,9 +133,6 @@ typedef CallbackObjectHolder<NodeFilter, nsIDOMNodeFilter> NodeFilterHolder;
{ 0x0300e2e0, 0x24c9, 0x4ecf, \
{ 0x81, 0xec, 0x64, 0x26, 0x9a, 0x4b, 0xef, 0x18 } }
// Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
// Enum for requesting a particular type of document when creating a doc
enum DocumentFlavor {
DocumentFlavorLegacyGuess, // compat with old code until made HTML5-compliant
@ -761,7 +758,29 @@ public:
*/
/**
* Get the number of stylesheets
* These exists to allow us to on-demand load user-agent style sheets that
* would otherwise be loaded by nsDocumentViewer::CreateStyleSet. This allows
* us to keep the memory used by a document's rule cascade data (the stuff in
* its nsStyleSet's nsCSSRuleProcessors) - which can be considerable - lower
* than it would be if we loaded all built-in user-agent style sheets up
* front.
*
* By "built-in" user-agent style sheets we mean the user-agent style sheets
* that gecko itself supplies (such as html.css and svg.css) as opposed to
* user-agent level style sheets inserted by add-ons or the like.
*
* This function prepends the given style sheet to the document's style set
* in order to make sure that it does not override user-agent style sheets
* supplied by add-ons or by the app (Firefox OS or Firefox Mobile, for
* example), since their sheets should override built-in sheets.
*
* TODO We can get rid of the whole concept of delayed loading if we fix
* bug 77999.
*/
virtual void EnsureOnDemandBuiltInUASheet(const char *aStyleSheetURI) = 0;
/**
* Get the number of (document) stylesheets
*
* @return the number of stylesheets
* @throws no exceptions
@ -821,15 +840,6 @@ public:
virtual void SetStyleSheetApplicableState(nsIStyleSheet* aSheet,
bool aApplicable) = 0;
/**
* Just like the style sheet API, but for "catalog" sheets,
* extra sheets inserted at the UA level.
*/
virtual int32_t GetNumberOfCatalogStyleSheets() const = 0;
virtual nsIStyleSheet* GetCatalogStyleSheetAt(int32_t aIndex) const = 0;
virtual void AddCatalogStyleSheet(nsCSSStyleSheet* aSheet) = 0;
virtual void EnsureCatalogStyleSheet(const char *aStyleSheetURI) = 0;
enum additionalSheetType {
eAgentSheet,
eUserSheet,

View File

@ -1691,14 +1691,10 @@ nsDocument::~nsDocument()
while (--indx >= 0) {
mStyleSheets[indx]->SetOwningDocument(nullptr);
}
indx = mCatalogSheets.Count();
while (--indx >= 0) {
static_cast<nsCSSStyleSheet*>(mCatalogSheets[indx])->SetOwningNode(nullptr);
mCatalogSheets[indx]->SetOwningDocument(nullptr);
}
if (mAttrStyleSheet) {
mAttrStyleSheet->SetOwningDocument(nullptr);
}
// We don't own the mOnDemandBuiltInUASheets, so we don't need to reset them.
if (mListenerManager) {
mListenerManager->Disconnect();
@ -1972,7 +1968,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
// Traverse all our nsCOMArrays.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCatalogSheets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnDemandBuiltInUASheets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPreloadingImages)
for (uint32_t i = 0; i < tmp->mFrameRequestCallbacks.Length(); ++i) {
@ -2417,13 +2413,14 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
mozAutoDocUpdate upd(this, UPDATE_STYLE, true);
RemoveDocStyleSheetsFromStyleSets();
RemoveStyleSheetsFromStyleSets(mCatalogSheets, nsStyleSet::eAgentSheet);
RemoveStyleSheetsFromStyleSets(mOnDemandBuiltInUASheets, nsStyleSet::eAgentSheet);
RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eAgentSheet], nsStyleSet::eAgentSheet);
RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eUserSheet], nsStyleSet::eUserSheet);
RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eAuthorSheet], nsStyleSet::eDocSheet);
// Release all the sheets
mStyleSheets.Clear();
mOnDemandBuiltInUASheets.Clear();
for (uint32_t i = 0; i < SheetTypeCount; ++i)
mAdditionalSheets[i].Clear();
@ -2495,10 +2492,11 @@ nsDocument::FillStyleSet(nsStyleSet* aStyleSet)
aStyleSet);
}
for (i = mCatalogSheets.Count() - 1; i >= 0; --i) {
nsIStyleSheet* sheet = mCatalogSheets[i];
// Iterate backwards to maintain order
for (i = mOnDemandBuiltInUASheets.Count() - 1; i >= 0; --i) {
nsIStyleSheet* sheet = mOnDemandBuiltInUASheets[i];
if (sheet->IsApplicable()) {
aStyleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, sheet);
aStyleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
}
}
@ -3981,6 +3979,57 @@ nsDocument::RemoveChildAt(uint32_t aIndex, bool aNotify)
mCachedRootElement = nullptr;
}
void
nsDocument::EnsureOnDemandBuiltInUASheet(const char* aStyleSheetURI)
{
mozilla::css::Loader* cssLoader = CSSLoader();
if (!cssLoader->GetEnabled()) {
return;
}
int32_t sheetCount = mOnDemandBuiltInUASheets.Count();
for (int32_t i = 0; i < sheetCount; i++) {
nsIStyleSheet* sheet = mOnDemandBuiltInUASheets[i];
NS_ASSERTION(sheet, "unexpected null stylesheet in the document");
if (sheet) {
nsAutoCString uriStr;
sheet->GetSheetURI()->GetSpec(uriStr);
if (uriStr.Equals(aStyleSheetURI))
return;
}
}
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), aStyleSheetURI);
if (uri) {
nsRefPtr<nsCSSStyleSheet> sheet;
cssLoader->LoadSheetSync(uri, true, true, getter_AddRefs(sheet));
if (sheet) {
BeginUpdate(UPDATE_STYLE);
AddOnDemandBuiltInUASheet(sheet);
EndUpdate(UPDATE_STYLE);
}
}
}
void
nsDocument::AddOnDemandBuiltInUASheet(nsCSSStyleSheet* aSheet)
{
// Prepend here so that we store the sheets in mOnDemandBuiltInUASheets in
// the same order that they should end up in the style set.
mOnDemandBuiltInUASheets.InsertElementAt(0, aSheet);
if (aSheet->IsApplicable()) {
// This is like |AddStyleSheetToStyleSets|, but for an agent sheet.
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
shell->StyleSet()->PrependStyleSheet(nsStyleSet::eAgentSheet, aSheet);
}
}
NotifyStyleSheetAdded(aSheet, false);
}
int32_t
nsDocument::GetNumberOfStyleSheets() const
{
@ -4212,71 +4261,6 @@ nsDocument::NotifyStyleSheetApplicableStateChanged()
}
}
// These three functions are a lot like the implementation of the
// corresponding API for regular stylesheets.
int32_t
nsDocument::GetNumberOfCatalogStyleSheets() const
{
return mCatalogSheets.Count();
}
nsIStyleSheet*
nsDocument::GetCatalogStyleSheetAt(int32_t aIndex) const
{
NS_ENSURE_TRUE(0 <= aIndex && aIndex < mCatalogSheets.Count(), nullptr);
return mCatalogSheets[aIndex];
}
void
nsDocument::AddCatalogStyleSheet(nsCSSStyleSheet* aSheet)
{
mCatalogSheets.AppendObject(aSheet);
aSheet->SetOwningDocument(this);
aSheet->SetOwningNode(this);
if (aSheet->IsApplicable()) {
// This is like |AddStyleSheetToStyleSets|, but for an agent sheet.
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
shell->StyleSet()->AppendStyleSheet(nsStyleSet::eAgentSheet, aSheet);
}
}
NotifyStyleSheetAdded(aSheet, false);
}
void
nsDocument::EnsureCatalogStyleSheet(const char *aStyleSheetURI)
{
mozilla::css::Loader* cssLoader = CSSLoader();
if (cssLoader->GetEnabled()) {
int32_t sheetCount = GetNumberOfCatalogStyleSheets();
for (int32_t i = 0; i < sheetCount; i++) {
nsIStyleSheet* sheet = GetCatalogStyleSheetAt(i);
NS_ASSERTION(sheet, "unexpected null stylesheet in the document");
if (sheet) {
nsAutoCString uriStr;
sheet->GetSheetURI()->GetSpec(uriStr);
if (uriStr.Equals(aStyleSheetURI))
return;
}
}
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), aStyleSheetURI);
if (uri) {
nsRefPtr<nsCSSStyleSheet> sheet;
cssLoader->LoadSheetSync(uri, true, true, getter_AddRefs(sheet));
if (sheet) {
BeginUpdate(UPDATE_STYLE);
AddCatalogStyleSheet(sheet);
EndUpdate(UPDATE_STYLE);
}
}
}
}
static nsStyleSet::sheetType
ConvertAdditionalSheetType(nsIDocument::additionalSheetType aType)
{
@ -9705,21 +9689,21 @@ nsIDocument::FlushPendingLinkUpdates()
already_AddRefed<nsIDocument>
nsIDocument::CreateStaticClone(nsIDocShell* aCloneContainer)
{
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(this);
NS_ENSURE_TRUE(domDoc, nullptr);
nsDocument* thisAsDoc = static_cast<nsDocument*>(this);
mCreatingStaticClone = true;
// Make document use different container during cloning.
nsRefPtr<nsDocShell> originalShell = mDocumentContainer.get();
SetContainer(static_cast<nsDocShell*>(aCloneContainer));
nsCOMPtr<nsIDOMNode> clonedNode;
nsresult rv = domDoc->CloneNode(true, 1, getter_AddRefs(clonedNode));
nsresult rv = thisAsDoc->CloneNode(true, 1, getter_AddRefs(clonedNode));
SetContainer(originalShell);
nsCOMPtr<nsIDocument> clonedDoc;
nsRefPtr<nsDocument> clonedDoc;
if (NS_SUCCEEDED(rv)) {
clonedDoc = do_QueryInterface(clonedNode);
if (clonedDoc) {
nsCOMPtr<nsIDocument> tmp = do_QueryInterface(clonedNode);
if (tmp) {
clonedDoc = static_cast<nsDocument*>(tmp.get());
if (IsStaticDocument()) {
clonedDoc->mOriginalDocument = mOriginalDocument;
} else {
@ -9740,17 +9724,18 @@ nsIDocument::CreateStaticClone(nsIDocShell* aCloneContainer)
}
}
sheetsCount = GetNumberOfCatalogStyleSheets();
for (int32_t i = 0; i < sheetsCount; ++i) {
sheetsCount = thisAsDoc->mOnDemandBuiltInUASheets.Count();
// Iterate backwards to maintain order
for (int32_t i = sheetsCount - 1; i >= 0; --i) {
nsRefPtr<nsCSSStyleSheet> sheet =
do_QueryObject(GetCatalogStyleSheetAt(i));
do_QueryObject(thisAsDoc->mOnDemandBuiltInUASheets[i]);
if (sheet) {
if (sheet->IsApplicable()) {
nsRefPtr<nsCSSStyleSheet> clonedSheet =
sheet->Clone(nullptr, nullptr, clonedDoc, nullptr);
NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!");
if (clonedSheet) {
clonedDoc->AddCatalogStyleSheet(clonedSheet);
clonedDoc->AddOnDemandBuiltInUASheet(clonedSheet);
}
}
}
@ -12011,8 +11996,8 @@ nsDocument::DocAddSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const
mStyleSheets.SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,
aWindowSizes->mMallocSizeOf);
aWindowSizes->mStyleSheetsSize +=
mCatalogSheets.SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,
aWindowSizes->mMallocSizeOf);
mOnDemandBuiltInUASheets.SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,
aWindowSizes->mMallocSizeOf);
aWindowSizes->mStyleSheetsSize +=
mAdditionalSheets[eAgentSheet].
SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,

View File

@ -672,6 +672,8 @@ class nsDocument : public nsIDocument,
public nsIObserver,
public nsIDOMXPathEvaluator
{
friend class nsIDocument;
public:
typedef mozilla::dom::Element Element;
using nsIDocument::GetElementsByTagName;
@ -779,8 +781,10 @@ public:
virtual Element* FindContentForSubDocument(nsIDocument *aDocument) const MOZ_OVERRIDE;
virtual Element* GetRootElementInternal() const MOZ_OVERRIDE;
virtual void EnsureOnDemandBuiltInUASheet(const char *aStyleSheetURI) MOZ_OVERRIDE;
/**
* Get the style sheets owned by this document.
* Get the (document) style sheets owned by this document.
* These are ordered, highest priority last
*/
virtual int32_t GetNumberOfStyleSheets() const MOZ_OVERRIDE;
@ -798,11 +802,6 @@ public:
virtual void SetStyleSheetApplicableState(nsIStyleSheet* aSheet,
bool aApplicable) MOZ_OVERRIDE;
virtual int32_t GetNumberOfCatalogStyleSheets() const MOZ_OVERRIDE;
virtual nsIStyleSheet* GetCatalogStyleSheetAt(int32_t aIndex) const MOZ_OVERRIDE;
virtual void AddCatalogStyleSheet(nsCSSStyleSheet* aSheet) MOZ_OVERRIDE;
virtual void EnsureCatalogStyleSheet(const char *aStyleSheetURI) MOZ_OVERRIDE;
virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI) MOZ_OVERRIDE;
virtual void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI) MOZ_OVERRIDE;
virtual nsIStyleSheet* FirstAdditionalAuthorSheet() MOZ_OVERRIDE;
@ -928,6 +927,7 @@ public:
virtual nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize) MOZ_OVERRIDE;
private:
void AddOnDemandBuiltInUASheet(nsCSSStyleSheet* aSheet);
nsRadioGroupStruct* GetRadioGroupInternal(const nsAString& aName) const;
void SendToConsole(nsCOMArray<nsISecurityConsoleMessage>& aMessages);
@ -1423,7 +1423,7 @@ protected:
nsWeakPtr mWeakSink;
nsCOMArray<nsIStyleSheet> mStyleSheets;
nsCOMArray<nsIStyleSheet> mCatalogSheets;
nsCOMArray<nsIStyleSheet> mOnDemandBuiltInUASheets;
nsCOMArray<nsIStyleSheet> mAdditionalSheets[SheetTypeCount];
// Array of observers

View File

@ -108,7 +108,7 @@ nsMathMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
// construction, because we could move a MathML element from the document
// that created it to another document.
aDocument->SetMathMLEnabled();
aDocument->EnsureCatalogStyleSheet(kMathMLStyleSheetURI);
aDocument->EnsureOnDemandBuiltInUASheet(kMathMLStyleSheetURI);
// Rebuild style data for the presshell, because style system
// optimizations may have taken place assuming MathML was disabled.

View File

@ -754,7 +754,7 @@ SVGSVGElement::BindToTree(nsIDocument* aDocument,
// 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.
aDocument->EnsureCatalogStyleSheet(kSVGStyleSheetURI);
aDocument->EnsureOnDemandBuiltInUASheet(kSVGStyleSheetURI);
}
if (mTimedDocumentRoot && smilController) {

View File

@ -1187,26 +1187,8 @@ nsXMLContentSink::HandleDoctypeDecl(const nsAString & aSubset,
return rv;
}
if (aCatalogData && mCSSLoader && mDocument) {
// bug 124570 - we only expect additional agent sheets for now -- ignore
// exit codes, error are not fatal here, just that the stylesheet won't apply
nsCOMPtr<nsIURI> uri(do_QueryInterface(aCatalogData));
if (uri) {
nsRefPtr<nsCSSStyleSheet> sheet;
mCSSLoader->LoadSheetSync(uri, true, true, getter_AddRefs(sheet));
#ifdef DEBUG
nsAutoCString uriStr;
uri->GetSpec(uriStr);
printf("Loading catalog stylesheet: %s ... %s\n", uriStr.get(), sheet.get() ? "Done" : "Failed");
#endif
if (sheet) {
mDocument->BeginUpdate(UPDATE_STYLE);
mDocument->AddCatalogStyleSheet(sheet);
mDocument->EndUpdate(UPDATE_STYLE);
}
}
}
MOZ_ASSERT(!aCatalogData, "Need to add back support for catalog style "
"sheets");
nsCOMPtr<nsIContent> content = do_QueryInterface(docType);
NS_ASSERTION(content, "doctype isn't content?");

View File

@ -264,9 +264,9 @@ static const nsCatalogData kCatalogTable[] = {
{ "-//W3C//DTD XHTML 1.0 Strict//EN", "htmlmathml-f.ent", nullptr },
{ "-//W3C//DTD XHTML 1.0 Frameset//EN", "htmlmathml-f.ent", nullptr },
{ "-//W3C//DTD XHTML Basic 1.0//EN", "htmlmathml-f.ent", nullptr },
{ "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN", "htmlmathml-f.ent", "resource://gre-resources/mathml.css" },
{ "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN", "htmlmathml-f.ent", "resource://gre-resources/mathml.css" },
{ "-//W3C//DTD MathML 2.0//EN", "htmlmathml-f.ent", "resource://gre-resources/mathml.css" },
{ "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN", "htmlmathml-f.ent", nullptr },
{ "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN", "htmlmathml-f.ent", nullptr },
{ "-//W3C//DTD MathML 2.0//EN", "htmlmathml-f.ent", nullptr },
{ "-//WAPFORUM//DTD XHTML Mobile 1.0//EN", "htmlmathml-f.ent", nullptr },
{ nullptr, nullptr, nullptr }
};
@ -629,9 +629,16 @@ nsExpatDriver::HandleEndDoctypeDecl()
// document (currently, from bug 124570, we only expect to pass additional
// agent sheets needed to layout the XML vocabulary of the document)
nsCOMPtr<nsIURI> data;
#if 0
if (mCatalogData && mCatalogData->mAgentSheet) {
NS_NewURI(getter_AddRefs(data), mCatalogData->mAgentSheet);
}
#endif
// The unused support for "catalog style sheets" was removed. It doesn't
// look like we'll ever fix bug 98413 either.
MOZ_ASSERT(!mCatalogData || !mCatalogData->mAgentSheet,
"Need to add back support for catalog style sheets");
// Note: mInternalSubset already doesn't include the [] around it.
nsresult rv = mSink->HandleDoctypeDecl(mInternalSubset, mDoctypeName,

View File

@ -47,7 +47,7 @@ addTest(function inheritedUserStyles() {
promiseDone(gWalker.querySelector(gWalker.rootNode, "#svgcontent rect").then(node => {
return gStyles.getApplied(node, { inherited: true, filter: "user" });
}).then(applied => {
is(applied.length, 3, "Should have 3 rules");
is(applied.length, 2, "Should have 2 rules");
is(applied[1].rule.cssText, "fill: rgb(1, 2, 3);", "cssText is right");
}).then(runNextTest));
});