Bug 508725 - Part 2: Record on nsCSSStyleSheets whether they are for a <style scoped>. r=dbaron

This commit is contained in:
Cameron McCormack 2013-01-08 19:09:22 +11:00
parent 993c756dda
commit f8c50ba688
11 changed files with 96 additions and 18 deletions

View File

@ -2027,6 +2027,25 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
}
}
void
nsDocument::RemoveDocStyleSheetsFromStyleSets()
{
// The stylesheets should forget us
int32_t indx = mStyleSheets.Count();
while (--indx >= 0) {
nsIStyleSheet* sheet = mStyleSheets[indx];
sheet->SetOwningDocument(nullptr);
if (sheet->IsApplicable()) {
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
shell->StyleSet()->RemoveDocStyleSheet(sheet);
}
}
// XXX Tell observers?
}
}
void
nsDocument::RemoveStyleSheetsFromStyleSets(nsCOMArray<nsIStyleSheet>& aSheets, nsStyleSet::sheetType aType)
{
@ -2054,7 +2073,7 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
NS_PRECONDITION(aURI, "Null URI passed to ResetStylesheetsToURI");
mozAutoDocUpdate upd(this, UPDATE_STYLE, true);
RemoveStyleSheetsFromStyleSets(mStyleSheets, nsStyleSet::eDocSheet);
RemoveDocStyleSheetsFromStyleSets();
RemoveStyleSheetsFromStyleSets(mCatalogSheets, nsStyleSet::eAgentSheet);
RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eAgentSheet], nsStyleSet::eAgentSheet);
RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eUserSheet], nsStyleSet::eUserSheet);
@ -3503,7 +3522,7 @@ nsDocument::RemoveStyleSheetFromStyleSets(nsIStyleSheet* aSheet)
{
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
shell->StyleSet()->RemoveStyleSheet(nsStyleSet::eDocSheet, aSheet);
shell->StyleSet()->RemoveDocStyleSheet(aSheet);
}
}

View File

@ -1080,6 +1080,7 @@ protected:
nsCompatibility aCompatMode,
nsIPresShell** aInstancePtrResult);
void RemoveDocStyleSheetsFromStyleSets();
void RemoveStyleSheetsFromStyleSets(nsCOMArray<nsIStyleSheet>& aSheets,
nsStyleSet::sheetType aType);
nsresult ResetStylesheetsToURI(nsIURI* aURI);

View File

@ -378,7 +378,7 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument *aOldDocument,
// Parse the style sheet.
rv = doc->CSSLoader()->
LoadInlineStyle(thisContent, text, mLineNumber, title, media,
aObserver, &doneLoading, &isAlternate);
scopeElement, aObserver, &doneLoading, &isAlternate);
}
else {
// XXXbz clone the URI here to work around content policies modifying URIs.

View File

@ -18,6 +18,7 @@
#include "mozilla/Util.h"
#include "mozilla/dom/Element.h"
#include "mozilla/css/Loader.h"
#include "nsIRunnable.h"
#include "nsIUnicharStreamLoader.h"
@ -70,6 +71,8 @@
#include "mozilla/dom/EncodingUtils.h"
using mozilla::dom::EncodingUtils;
using namespace mozilla::dom;
/**
* OVERALL ARCHITECTURE
*
@ -1206,6 +1209,7 @@ Loader::PrepareSheet(nsCSSStyleSheet* aSheet,
const nsSubstring& aTitle,
const nsSubstring& aMediaString,
nsMediaList* aMediaList,
Element* aScopeElement,
bool isAlternate)
{
NS_PRECONDITION(aSheet, "Must have a sheet!");
@ -1232,6 +1236,7 @@ Loader::PrepareSheet(nsCSSStyleSheet* aSheet,
aSheet->SetTitle(aTitle);
aSheet->SetEnabled(! isAlternate);
aSheet->SetScopeElement(aScopeElement);
return NS_OK;
}
@ -1794,6 +1799,7 @@ Loader::LoadInlineStyle(nsIContent* aElement,
uint32_t aLineNumber,
const nsAString& aTitle,
const nsAString& aMedia,
Element* aScopeElement,
nsICSSLoaderObserver* aObserver,
bool* aCompleted,
bool* aIsAlternate)
@ -1826,7 +1832,8 @@ Loader::LoadInlineStyle(nsIContent* aElement,
LOG((" Sheet is alternate: %d", *aIsAlternate));
rv = PrepareSheet(sheet, aTitle, aMedia, nullptr, *aIsAlternate);
rv = PrepareSheet(sheet, aTitle, aMedia, nullptr, aScopeElement,
*aIsAlternate);
NS_ENSURE_SUCCESS(rv, rv);
rv = InsertSheetInDoc(sheet, aElement, mDocument);
@ -1899,7 +1906,7 @@ Loader::LoadStyleLink(nsIContent* aElement,
LOG((" Sheet is alternate: %d", *aIsAlternate));
rv = PrepareSheet(sheet, aTitle, aMedia, nullptr, *aIsAlternate);
rv = PrepareSheet(sheet, aTitle, aMedia, nullptr, nullptr, *aIsAlternate);
NS_ENSURE_SUCCESS(rv, rv);
rv = InsertSheetInDoc(sheet, aElement, mDocument);
@ -2057,7 +2064,7 @@ Loader::LoadChildSheet(nsCSSStyleSheet* aParentSheet,
false, empty, state, &isAlternate, getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv);
rv = PrepareSheet(sheet, empty, empty, aMedia, isAlternate);
rv = PrepareSheet(sheet, empty, empty, aMedia, nullptr, isAlternate);
NS_ENSURE_SUCCESS(rv, rv);
rv = InsertChildSheet(sheet, aParentSheet, aParentRule);
@ -2168,7 +2175,7 @@ Loader::InternalLoadNonDocumentSheet(nsIURI* aURL,
empty, state, &isAlternate, getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv);
rv = PrepareSheet(sheet, empty, empty, nullptr, isAlternate);
rv = PrepareSheet(sheet, empty, empty, nullptr, nullptr, isAlternate);
NS_ENSURE_SUCCESS(rv, rv);
if (state == eSheetComplete) {

View File

@ -31,6 +31,12 @@ class nsMediaList;
class nsIStyleSheetLinkingElement;
class nsCycleCollectionTraversalCallback;
namespace mozilla {
namespace dom {
class Element;
}
}
namespace mozilla {
class URIPrincipalAndCORSModeHashKey : public nsURIHashKey
@ -160,6 +166,7 @@ public:
uint32_t aLineNumber,
const nsAString& aTitle,
const nsAString& aMedia,
mozilla::dom::Element* aScopeElement,
nsICSSLoaderObserver* aObserver,
bool* aCompleted,
bool* aIsAlternate);
@ -395,6 +402,7 @@ private:
const nsAString& aTitle,
const nsAString& aMediaString,
nsMediaList* aMediaList,
mozilla::dom::Element* aScopeElement,
bool isAlternate);
nsresult InsertSheetInDoc(nsCSSStyleSheet* aSheet,

View File

@ -11,6 +11,7 @@
#include "nsCRT.h"
#include "nsIAtom.h"
#include "nsCSSRuleProcessor.h"
#include "mozilla/dom/Element.h"
#include "mozilla/css/NameSpaceRule.h"
#include "mozilla/css/GroupRule.h"
#include "mozilla/css/ImportRule.h"
@ -41,6 +42,7 @@
#include "mozilla/Likely.h"
using namespace mozilla;
using namespace mozilla::dom;
// -------------------------------
@ -1033,6 +1035,7 @@ nsCSSStyleSheet::nsCSSStyleSheet(CORSMode aCORSMode)
mOwningNode(nullptr),
mDisabled(false),
mDirty(false),
mScopeElement(nullptr),
mRuleProcessors(nullptr)
{
@ -1051,6 +1054,7 @@ nsCSSStyleSheet::nsCSSStyleSheet(const nsCSSStyleSheet& aCopy,
mOwningNode(aOwningNodeToUse),
mDisabled(aCopy.mDisabled),
mDirty(aCopy.mDirty),
mScopeElement(nullptr),
mInner(aCopy.mInner),
mRuleProcessors(nullptr)
{
@ -1197,12 +1201,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSStyleSheet)
// unlinked before it does.
tmp->DropRuleCollection();
tmp->UnlinkInner();
tmp->mScopeElement = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSStyleSheet)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMedia)
// We do not traverse mNext; our parent will handle that. See
// comments in Unlink for why.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRuleCollection)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScopeElement)
tmp->TraverseInner(cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END

View File

@ -10,6 +10,7 @@
#define nsCSSStyleSheet_h_
#include "mozilla/Attributes.h"
#include "mozilla/dom/Element.h"
#include "nscore.h"
#include "nsCOMPtr.h"
@ -247,6 +248,12 @@ public:
// Get this style sheet's CORS mode
mozilla::CORSMode GetCORSMode() const { return mInner->mCORSMode; }
mozilla::dom::Element* GetScopeElement() const { return mScopeElement; }
void SetScopeElement(mozilla::dom::Element* aScopeElement)
{
mScopeElement = aScopeElement;
}
private:
nsCSSStyleSheet(const nsCSSStyleSheet& aCopy,
nsCSSStyleSheet* aParentToUse,
@ -297,6 +304,7 @@ protected:
nsIDOMNode* mOwningNode; // weak ref
bool mDisabled;
bool mDirty; // has been modified
nsRefPtr<mozilla::dom::Element> mScopeElement;
nsCSSStyleSheetInner* mInner;

View File

@ -25,7 +25,7 @@ struct nsRuleData
const uint32_t mSIDs;
bool mCanStoreInRuleTree;
bool mIsImportantRule;
uint8_t mLevel; // an nsStyleSet::sheetType
uint16_t mLevel; // an nsStyleSet::sheetType
nsPresContext* const mPresContext;
nsStyleContext* const mStyleContext;
const nsPostResolveFunc mPostResolveCallback;

View File

@ -645,7 +645,7 @@ public:
nsRuleNode* GetParent() const { return mParent; }
bool IsRoot() const { return mParent == nullptr; }
// These PRUint8s are really nsStyleSet::sheetType values.
// These uint8_ts are really nsStyleSet::sheetType values.
uint8_t GetLevel() const {
NS_ASSERTION(!IsRoot(), "can't call on root");
return (mDependentBits & NS_RULE_NODE_LEVEL_MASK) >>

View File

@ -100,6 +100,7 @@ static const nsStyleSet::sheetType gCSSSheetTypes[] = {
nsStyleSet::eAgentSheet,
nsStyleSet::eUserSheet,
nsStyleSet::eDocSheet,
nsStyleSet::eScopedDocSheet,
nsStyleSet::eOverrideSheet
};
@ -261,6 +262,15 @@ nsStyleSet::GatherRuleProcessors(sheetType aType)
return NS_OK;
}
static bool
IsScopedStyleSheet(nsIStyleSheet* aSheet)
{
nsRefPtr<nsCSSStyleSheet> cssSheet = do_QueryObject(aSheet);
NS_ASSERTION(cssSheet, "expected aSheet to be an nsCSSStyleSheet");
return cssSheet->GetScopeElement();
}
nsresult
nsStyleSet::AppendStyleSheet(sheetType aType, nsIStyleSheet *aSheet)
{
@ -376,18 +386,21 @@ nsStyleSet::AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument)
NS_ASSERTION(aSheet->IsApplicable(),
"Inapplicable sheet being placed in style set");
nsCOMArray<nsIStyleSheet>& docSheets = mSheets[eDocSheet];
sheetType type = IsScopedStyleSheet(aSheet) ?
eScopedDocSheet :
eDocSheet;
nsCOMArray<nsIStyleSheet>& sheets = mSheets[type];
docSheets.RemoveObject(aSheet);
sheets.RemoveObject(aSheet);
nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
// lowest index first
int32_t newDocIndex = aDocument->GetIndexOfStyleSheet(aSheet);
int32_t count = docSheets.Count();
int32_t count = sheets.Count();
int32_t index;
for (index = 0; index < count; index++) {
nsIStyleSheet* sheet = docSheets.ObjectAt(index);
nsIStyleSheet* sheet = sheets.ObjectAt(index);
int32_t sheetDocIndex = aDocument->GetIndexOfStyleSheet(sheet);
if (sheetDocIndex > newDocIndex)
break;
@ -402,15 +415,23 @@ nsStyleSet::AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument)
sheet == aDocument->FirstAdditionalAuthorSheet()))
break;
}
if (!docSheets.InsertObjectAt(aSheet, index))
if (!sheets.InsertObjectAt(aSheet, index))
return NS_ERROR_OUT_OF_MEMORY;
if (!mBatching)
return GatherRuleProcessors(eDocSheet);
return GatherRuleProcessors(type);
mDirty |= 1 << eDocSheet;
mDirty |= 1 << type;
return NS_OK;
}
nsresult
nsStyleSet::RemoveDocStyleSheet(nsIStyleSheet *aSheet)
{
nsRefPtr<nsCSSStyleSheet> cssSheet = do_QueryObject(aSheet);
bool isScoped = cssSheet && cssSheet->GetScopeElement();
return RemoveStyleSheet(isScoped ? eScopedDocSheet : eDocSheet, aSheet);
}
// Batching
void
nsStyleSet::BeginUpdate()
@ -1259,6 +1280,8 @@ nsStyleSet::AppendFontFaceRules(nsPresContext* aPresContext,
NS_ENSURE_FALSE(mInShutdown, false);
for (uint32_t i = 0; i < ArrayLength(gCSSSheetTypes); ++i) {
if (gCSSSheetTypes[i] == eScopedDocSheet)
continue;
nsCSSRuleProcessor *ruleProc = static_cast<nsCSSRuleProcessor*>
(mRuleProcessors[gCSSSheetTypes[i]].get());
if (ruleProc && !ruleProc->AppendFontFaceRules(aPresContext, aArray))
@ -1274,6 +1297,8 @@ nsStyleSet::AppendKeyframesRules(nsPresContext* aPresContext,
NS_ENSURE_FALSE(mInShutdown, false);
for (uint32_t i = 0; i < ArrayLength(gCSSSheetTypes); ++i) {
if (gCSSSheetTypes[i] == eScopedDocSheet)
continue;
nsCSSRuleProcessor *ruleProc = static_cast<nsCSSRuleProcessor*>
(mRuleProcessors[gCSSSheetTypes[i]].get());
if (ruleProc && !ruleProc->AppendKeyframesRules(aPresContext, aArray))
@ -1289,6 +1314,8 @@ nsStyleSet::AppendPageRules(nsPresContext* aPresContext,
NS_ENSURE_FALSE(mInShutdown, false);
for (uint32_t i = 0; i < NS_ARRAY_LENGTH(gCSSSheetTypes); ++i) {
if (gCSSSheetTypes[i] == eScopedDocSheet)
continue;
nsCSSRuleProcessor* ruleProc = static_cast<nsCSSRuleProcessor*>
(mRuleProcessors[gCSSSheetTypes[i]].get());
if (ruleProc && !ruleProc->AppendPageRules(aPresContext, aArray))

View File

@ -233,6 +233,7 @@ class nsStyleSet
eUserSheet, // CSS
ePresHintSheet,
eDocSheet, // CSS
eScopedDocSheet,
eStyleAttrSheet,
eOverrideSheet, // CSS
eAnimationSheet,
@ -253,7 +254,7 @@ class nsStyleSet
nsresult InsertStyleSheetBefore(sheetType aType, nsIStyleSheet *aNewSheet,
nsIStyleSheet *aReferenceSheet);
// Enable/Disable entire author style level (Doc & PresHint levels)
// Enable/Disable entire author style level (Doc, ScopedDoc & PresHint levels)
bool GetAuthorStyleDisabled();
nsresult SetAuthorStyleDisabled(bool aStyleDisabled);
@ -265,6 +266,7 @@ class nsStyleSet
return mSheets[aType].ObjectAt(aIndex);
}
nsresult RemoveDocStyleSheet(nsIStyleSheet* aSheet);
nsresult AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument);
void BeginUpdate();
@ -388,7 +390,7 @@ class nsStyleSet
unsigned mInShutdown : 1;
unsigned mAuthorStyleDisabled: 1;
unsigned mInReconstruct : 1;
unsigned mDirty : 8; // one dirty bit is used per sheet type
unsigned mDirty : 9; // one dirty bit is used per sheet type
uint32_t mUnusedRuleNodeCount; // used to batch rule node GC
nsTArray<nsStyleContext*> mRoots; // style contexts with no parent