Bug 1089417 patch 6 - Pass the previous CSS rule processor to the constructor of the new one (when we replace one with another). r=heycam

This is needed for patch 7.
This commit is contained in:
L. David Baron 2014-12-05 11:37:38 -08:00
parent 27254fec85
commit c4977dbae7
4 changed files with 36 additions and 7 deletions

View File

@ -78,7 +78,6 @@ nsXBLPrototypeResources::FlushSkinSheets()
// We have scoped stylesheets. Reload any chrome stylesheets we
// encounter. (If they aren't skin sheets, it doesn't matter, since
// they'll still be in the chrome cache.
mRuleProcessor = nullptr;
nsTArray<nsRefPtr<CSSStyleSheet>> oldSheets;
@ -144,7 +143,8 @@ nsXBLPrototypeResources::GatherRuleProcessor()
{
mRuleProcessor = new nsCSSRuleProcessor(mStyleSheetList,
nsStyleSet::eDocSheet,
nullptr);
nullptr,
mRuleProcessor);
}
void

View File

@ -1087,7 +1087,9 @@ RuleCascadeData::AttributeListFor(nsIAtom* aAttribute)
nsCSSRuleProcessor::nsCSSRuleProcessor(const sheet_array_type& aSheets,
uint8_t aSheetType,
Element* aScopeElement)
Element* aScopeElement,
nsCSSRuleProcessor*
aPreviousCSSRuleProcessor)
: mSheets(aSheets)
, mRuleCascades(nullptr)
, mLastPresContext(nullptr)

View File

@ -52,9 +52,12 @@ public:
// aScopeElement must be non-null iff aSheetType is
// nsStyleSet::eScopedDocSheet.
// aPreviousCSSRuleProcessor is the rule processor (if any) that this
// one is replacing.
nsCSSRuleProcessor(const sheet_array_type& aSheets,
uint8_t aSheetType,
mozilla::dom::Element* aScopeElement);
mozilla::dom::Element* aScopeElement,
nsCSSRuleProcessor* aPreviousCSSRuleProcessor);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(nsCSSRuleProcessor)

View File

@ -352,6 +352,9 @@ SortStyleSheetsByScope(nsTArray<CSSStyleSheet*>& aSheets)
nsresult
nsStyleSet::GatherRuleProcessors(sheetType aType)
{
nsCOMPtr<nsIStyleRuleProcessor> oldRuleProcessor(mRuleProcessors[aType]);
nsTArray<nsCOMPtr<nsIStyleRuleProcessor>> oldScopedDocRuleProcessors;
mRuleProcessors[aType] = nullptr;
if (aType == eScopedDocSheet) {
for (uint32_t i = 0; i < mScopedDocSheetRuleProcessors.Length(); i++) {
@ -360,7 +363,9 @@ nsStyleSet::GatherRuleProcessors(sheetType aType)
static_cast<nsCSSRuleProcessor*>(processor)->GetScopeElement();
scope->ClearIsScopedStyleRoot();
}
mScopedDocSheetRuleProcessors.Clear();
// Clear mScopedDocSheetRuleProcessors, but save it.
oldScopedDocRuleProcessors.SwapElements(mScopedDocSheetRuleProcessors);
}
if (mAuthorStyleDisabled && (aType == eDocSheet ||
aType == eScopedDocSheet ||
@ -420,6 +425,21 @@ nsStyleSet::GatherRuleProcessors(sheetType aType)
// adjacent and that ancestor scopes come before descendent scopes.
SortStyleSheetsByScope(sheets);
// Put the old scoped rule processors in a hashtable so that we
// can retrieve them efficiently, even in edge cases like the
// simultaneous removal and addition of a large number of elements
// with scoped sheets.
nsDataHashtable<nsPtrHashKey<Element>,
nsCSSRuleProcessor*> oldScopedRuleProcessorHash;
for (size_t i = oldScopedDocRuleProcessors.Length(); i-- != 0; ) {
nsCSSRuleProcessor* oldRP =
static_cast<nsCSSRuleProcessor*>(oldScopedDocRuleProcessors[i].get());
Element* scope = oldRP->GetScopeElement();
MOZ_ASSERT(!oldScopedRuleProcessorHash.Get(scope),
"duplicate rule processors for same scope element?");
oldScopedRuleProcessorHash.Put(scope, oldRP);
}
uint32_t start = 0, end;
do {
// Find the range of style sheets with the same scope.
@ -434,8 +454,10 @@ nsStyleSet::GatherRuleProcessors(sheetType aType)
// Create a rule processor for the scope.
nsTArray<nsRefPtr<CSSStyleSheet>> sheetsForScope;
sheetsForScope.AppendElements(sheets.Elements() + start, end - start);
nsCSSRuleProcessor* oldRP = oldScopedRuleProcessorHash.Get(scope);
mScopedDocSheetRuleProcessors.AppendElement
(new nsCSSRuleProcessor(sheetsForScope, uint8_t(aType), scope));
(new nsCSSRuleProcessor(sheetsForScope, uint8_t(aType), scope,
oldRP));
start = end;
} while (start < count);
@ -457,7 +479,9 @@ nsStyleSet::GatherRuleProcessors(sheetType aType)
cssSheets.AppendElement(cssSheet);
}
mRuleProcessors[aType] =
new nsCSSRuleProcessor(cssSheets, uint8_t(aType), nullptr);
new nsCSSRuleProcessor(cssSheets, uint8_t(aType), nullptr,
static_cast<nsCSSRuleProcessor*>(
oldRuleProcessor.get()));
} break;
default: