mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-30 11:18:39 +09:00
Issue #2828 - Part 5: Implement child rule processors
This commit is contained in:
parent
aab9cdf9bd
commit
e05d4d8306
16 changed files with 632 additions and 155 deletions
|
|
@ -55,6 +55,7 @@
|
|||
#include "nsIMozBrowserFrame.h"
|
||||
#include "RuleCascadeData.h"
|
||||
#include "nsCSSRuleUtils.h"
|
||||
#include "CascadeLayerRuleProcessor.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
|
@ -146,39 +147,30 @@ nsCSSRuleProcessor::ClearSheets()
|
|||
/* virtual */ void
|
||||
nsCSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData)
|
||||
{
|
||||
ResolvedRuleCascades* resolvedCascade = GetRuleCascade(aData->mPresContext);
|
||||
|
||||
if (!resolvedCascade) {
|
||||
return;
|
||||
}
|
||||
for (RuleCascadeData* cascade : resolvedCascade->mOrderedData) {
|
||||
cascade->RulesMatching(aData);
|
||||
if (ResolvedRuleCascades* cascades = GetRuleCascade(aData->mPresContext)) {
|
||||
for (nsCOMPtr<nsIStyleRuleProcessor> processor : cascades->mProcessors) {
|
||||
processor->RulesMatching(aData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
nsCSSRuleProcessor::RulesMatching(PseudoElementRuleProcessorData* aData)
|
||||
{
|
||||
ResolvedRuleCascades* resolvedCascade = GetRuleCascade(aData->mPresContext);
|
||||
|
||||
if (!resolvedCascade) {
|
||||
return;
|
||||
}
|
||||
for (RuleCascadeData* cascade : resolvedCascade->mOrderedData) {
|
||||
cascade->RulesMatching(aData);
|
||||
if (ResolvedRuleCascades* cascades = GetRuleCascade(aData->mPresContext)) {
|
||||
for (nsCOMPtr<nsIStyleRuleProcessor> processor : cascades->mProcessors) {
|
||||
processor->RulesMatching(aData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
nsCSSRuleProcessor::RulesMatching(AnonBoxRuleProcessorData* aData)
|
||||
{
|
||||
ResolvedRuleCascades* resolvedCascade = GetRuleCascade(aData->mPresContext);
|
||||
|
||||
if (!resolvedCascade) {
|
||||
return;
|
||||
}
|
||||
for (RuleCascadeData* cascade : resolvedCascade->mOrderedData) {
|
||||
cascade->RulesMatching(aData);
|
||||
if (ResolvedRuleCascades* cascades = GetRuleCascade(aData->mPresContext)) {
|
||||
for (nsCOMPtr<nsIStyleRuleProcessor> processor : cascades->mProcessors) {
|
||||
processor->RulesMatching(aData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -186,13 +178,10 @@ nsCSSRuleProcessor::RulesMatching(AnonBoxRuleProcessorData* aData)
|
|||
/* virtual */ void
|
||||
nsCSSRuleProcessor::RulesMatching(XULTreeRuleProcessorData* aData)
|
||||
{
|
||||
ResolvedRuleCascades* resolvedCascade = GetRuleCascade(aData->mPresContext);
|
||||
|
||||
if (!resolvedCascade) {
|
||||
return;
|
||||
}
|
||||
for (RuleCascadeData* cascade : resolvedCascade->mOrderedData) {
|
||||
cascade->RulesMatching(aData);
|
||||
if (ResolvedRuleCascades* cascades = GetRuleCascade(aData->mPresContext)) {
|
||||
for (nsCOMPtr<nsIStyleRuleProcessor> processor : cascades->mProcessors) {
|
||||
processor->RulesMatching(aData);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -207,19 +196,19 @@ nsCSSRuleProcessor::HasStateDependentStyle(ElementDependentRuleProcessorData* aD
|
|||
"mCurrentStyleScope will need to be saved and restored after the "
|
||||
"SelectorMatchesTree call");
|
||||
|
||||
ResolvedRuleCascades* resolvedCascade = GetRuleCascade(aData->mPresContext);
|
||||
|
||||
nsRestyleHint hint = nsRestyleHint(0);
|
||||
if (resolvedCascade) {
|
||||
for (RuleCascadeData* cascade : resolvedCascade->mOrderedData) {
|
||||
cascade->HasStateDependentStyle(
|
||||
if (ResolvedRuleCascades* cascades = GetRuleCascade(aData->mPresContext)) {
|
||||
for (nsCOMPtr<nsIStyleRuleProcessor> processor : cascades->mProcessors) {
|
||||
CascadeLayerRuleProcessor* layerProcessor =
|
||||
static_cast<CascadeLayerRuleProcessor*>(processor.get());
|
||||
layerProcessor->HasStateDependentStyle(
|
||||
aData, aStatefulElement, aPseudoType, aStateMask, hint);
|
||||
}
|
||||
}
|
||||
return hint;
|
||||
}
|
||||
|
||||
nsRestyleHint
|
||||
/* virtual */ nsRestyleHint
|
||||
nsCSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData)
|
||||
{
|
||||
return HasStateDependentStyle(aData,
|
||||
|
|
@ -228,7 +217,7 @@ nsCSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData)
|
|||
aData->mStateMask);
|
||||
}
|
||||
|
||||
nsRestyleHint
|
||||
/* virtual */ nsRestyleHint
|
||||
nsCSSRuleProcessor::HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData)
|
||||
{
|
||||
return HasStateDependentStyle(aData,
|
||||
|
|
@ -237,15 +226,12 @@ nsCSSRuleProcessor::HasStateDependentStyle(PseudoElementStateRuleProcessorData*
|
|||
aData->mStateMask);
|
||||
}
|
||||
|
||||
bool
|
||||
/* virtual */ bool
|
||||
nsCSSRuleProcessor::HasDocumentStateDependentStyle(StateRuleProcessorData* aData)
|
||||
{
|
||||
ResolvedRuleCascades* resolvedCascade = GetRuleCascade(aData->mPresContext);
|
||||
|
||||
if (resolvedCascade) {
|
||||
for (RuleCascadeData* cascade : resolvedCascade->mOrderedData) {
|
||||
if (cascade->mSelectorDocumentStates.HasAtLeastOneOfStates(
|
||||
aData->mStateMask)) {
|
||||
if (ResolvedRuleCascades* cascades = GetRuleCascade(aData->mPresContext)) {
|
||||
for (nsCOMPtr<nsIStyleRuleProcessor> processor : cascades->mProcessors) {
|
||||
if (processor->HasDocumentStateDependentStyle(aData)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -259,47 +245,15 @@ nsCSSRuleProcessor::HasAttributeDependentStyle(
|
|||
AttributeRuleProcessorData* aData,
|
||||
RestyleHintData& aRestyleHintDataResult)
|
||||
{
|
||||
// We could try making use of aData->mModType, but :not rules make it a bit
|
||||
// of a pain to do so... So just ignore it for now.
|
||||
|
||||
AttributeEnumData data(aData, aRestyleHintDataResult);
|
||||
|
||||
// Don't do our special handling of certain attributes if the attr
|
||||
// hasn't changed yet.
|
||||
if (aData->mAttrHasChanged) {
|
||||
// check for the lwtheme and lwthemetextcolor attribute on root XUL elements
|
||||
if ((aData->mAttribute == nsGkAtoms::lwtheme ||
|
||||
aData->mAttribute == nsGkAtoms::lwthemetextcolor) &&
|
||||
aData->mElement->GetNameSpaceID() == kNameSpaceID_XUL &&
|
||||
aData->mElement == aData->mElement->OwnerDoc()->GetRootElement())
|
||||
{
|
||||
data.change = nsRestyleHint(data.change | eRestyle_Subtree);
|
||||
}
|
||||
|
||||
// We don't know the namespace of the attribute, and xml:lang applies to
|
||||
// all elements. If the lang attribute changes, we need to restyle our
|
||||
// whole subtree, since the :lang selector on our descendants can examine
|
||||
// our lang attribute.
|
||||
if (aData->mAttribute == nsGkAtoms::lang) {
|
||||
data.change = nsRestyleHint(data.change | eRestyle_Subtree);
|
||||
}
|
||||
}
|
||||
|
||||
ResolvedRuleCascades* resolvedCascade = GetRuleCascade(aData->mPresContext);
|
||||
|
||||
// Since we get both before and after notifications for attributes, we
|
||||
// don't have to ignore aData->mAttribute while matching. Just check
|
||||
// whether we have selectors relevant to aData->mAttribute that we
|
||||
// match. If this is the before change notification, that will catch
|
||||
// rules we might stop matching; if the after change notification, the
|
||||
// ones we might have started matching.
|
||||
if (resolvedCascade) {
|
||||
for (RuleCascadeData* cascade : resolvedCascade->mOrderedData) {
|
||||
cascade->HasAttributeDependentStyle(
|
||||
if (ResolvedRuleCascades* cascades = GetRuleCascade(aData->mPresContext)) {
|
||||
for (nsCOMPtr<nsIStyleRuleProcessor> processor : cascades->mProcessors) {
|
||||
CascadeLayerRuleProcessor* layerProcessor =
|
||||
static_cast<CascadeLayerRuleProcessor*>(processor.get());
|
||||
layerProcessor->HasAttributeDependentStyle(
|
||||
aData, &data, aRestyleHintDataResult);
|
||||
}
|
||||
}
|
||||
|
||||
return data.change;
|
||||
}
|
||||
|
||||
|
|
@ -341,13 +295,21 @@ nsCSSRuleProcessor::MediumFeaturesChanged(nsPresContext* aPresContext)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* virtual */ nsTArray<nsCOMPtr<nsIStyleRuleProcessor>>*
|
||||
nsCSSRuleProcessor::GetChildRuleProcessors()
|
||||
{
|
||||
return mRuleCascades
|
||||
? &mRuleCascades->mProcessors
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
UniquePtr<nsMediaQueryResultCacheKey>
|
||||
nsCSSRuleProcessor::CloneMQCacheKey()
|
||||
{
|
||||
MOZ_ASSERT(!(mRuleCascades && mPreviousCacheKey));
|
||||
|
||||
ResolvedRuleCascades* c = mRuleCascades;
|
||||
if (!c || !c->mUnlayered) {
|
||||
if (!c) {
|
||||
// We might have an mPreviousCacheKey. It already comes from a call
|
||||
// to CloneMQCacheKey, so don't bother checking
|
||||
// HasFeatureConditions().
|
||||
|
|
@ -373,9 +335,9 @@ nsCSSRuleProcessor::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
|||
{
|
||||
size_t n = 0;
|
||||
n += mSheets.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
for (ResolvedRuleCascades* cascade = mRuleCascades; cascade;
|
||||
cascade = cascade->mNext) {
|
||||
n += cascade->SizeOfIncludingThis(aMallocSizeOf);
|
||||
for (ResolvedRuleCascades* cascades = mRuleCascades; cascades;
|
||||
cascades = cascades->mNext) {
|
||||
n += cascades->SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
return n;
|
||||
|
|
@ -387,18 +349,16 @@ nsCSSRuleProcessor::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
|||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
// Append all the currently-active font face rules to aArray. Return
|
||||
// true for success and false for failure.
|
||||
bool
|
||||
nsCSSRuleProcessor::AppendFontFaceRules(
|
||||
nsPresContext *aPresContext,
|
||||
nsTArray<nsFontFaceRuleContainer>& aArray)
|
||||
{
|
||||
ResolvedRuleCascades* resolvedCascade = GetRuleCascade(aPresContext);
|
||||
|
||||
if (resolvedCascade) {
|
||||
for (RuleCascadeData* cascade : resolvedCascade->mOrderedData) {
|
||||
if (!aArray.AppendElements(cascade->mFontFaceRules)) {
|
||||
if (ResolvedRuleCascades* cascades = GetRuleCascade(aPresContext)) {
|
||||
for (nsCOMPtr<nsIStyleRuleProcessor> processor : cascades->mProcessors) {
|
||||
CascadeLayerRuleProcessor* layerProcessor =
|
||||
static_cast<CascadeLayerRuleProcessor*>(processor.get());
|
||||
if (!layerProcessor->AppendFontFaceRules(aPresContext, aArray)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -411,13 +371,14 @@ nsCSSKeyframesRule*
|
|||
nsCSSRuleProcessor::KeyframesRuleForName(nsPresContext* aPresContext,
|
||||
const nsString& aName)
|
||||
{
|
||||
ResolvedRuleCascades* resolvedCascade = GetRuleCascade(aPresContext);
|
||||
|
||||
nsCSSKeyframesRule* rule = nullptr;
|
||||
if (resolvedCascade) {
|
||||
for (RuleCascadeData* cascade : resolvedCascade->mOrderedData) {
|
||||
|
||||
if (ResolvedRuleCascades* cascades = GetRuleCascade(aPresContext)) {
|
||||
for (nsCOMPtr<nsIStyleRuleProcessor> processor : cascades->mProcessors) {
|
||||
CascadeLayerRuleProcessor* layerProcessor =
|
||||
static_cast<CascadeLayerRuleProcessor*>(processor.get());
|
||||
if (nsCSSKeyframesRule* newRule =
|
||||
cascade->mKeyframesRuleTable.Get(aName)) {
|
||||
layerProcessor->KeyframesRuleForName(aPresContext, aName)) {
|
||||
rule = newRule;
|
||||
}
|
||||
}
|
||||
|
|
@ -430,13 +391,13 @@ nsCSSCounterStyleRule*
|
|||
nsCSSRuleProcessor::CounterStyleRuleForName(nsPresContext* aPresContext,
|
||||
const nsAString& aName)
|
||||
{
|
||||
ResolvedRuleCascades* resolvedCascade = GetRuleCascade(aPresContext);
|
||||
|
||||
nsCSSCounterStyleRule* rule = nullptr;
|
||||
if (resolvedCascade) {
|
||||
for (RuleCascadeData* cascade : resolvedCascade->mOrderedData) {
|
||||
if (ResolvedRuleCascades* cascades = GetRuleCascade(aPresContext)) {
|
||||
for (nsCOMPtr<nsIStyleRuleProcessor> processor : cascades->mProcessors) {
|
||||
CascadeLayerRuleProcessor* layerProcessor =
|
||||
static_cast<CascadeLayerRuleProcessor*>(processor.get());
|
||||
if (nsCSSCounterStyleRule* newRule =
|
||||
cascade->mCounterStyleRuleTable.Get(aName)) {
|
||||
layerProcessor->CounterStyleRuleForName(aPresContext, aName)) {
|
||||
rule = newRule;
|
||||
}
|
||||
}
|
||||
|
|
@ -445,18 +406,16 @@ nsCSSRuleProcessor::CounterStyleRuleForName(nsPresContext* aPresContext,
|
|||
return rule;
|
||||
}
|
||||
|
||||
// Append all the currently-active page rules to aArray. Return
|
||||
// true for success and false for failure.
|
||||
bool
|
||||
nsCSSRuleProcessor::AppendPageRules(
|
||||
nsPresContext* aPresContext,
|
||||
nsTArray<nsCSSPageRule*>& aArray)
|
||||
{
|
||||
ResolvedRuleCascades* resolvedCascade = GetRuleCascade(aPresContext);
|
||||
|
||||
if (resolvedCascade) {
|
||||
for (RuleCascadeData* cascade : resolvedCascade->mOrderedData) {
|
||||
if (!aArray.AppendElements(cascade->mPageRules)) {
|
||||
if (ResolvedRuleCascades* cascades = GetRuleCascade(aPresContext)) {
|
||||
for (nsCOMPtr<nsIStyleRuleProcessor> processor : cascades->mProcessors) {
|
||||
CascadeLayerRuleProcessor* layerProcessor =
|
||||
static_cast<CascadeLayerRuleProcessor*>(processor.get());
|
||||
if (!layerProcessor->AppendPageRules(aPresContext, aArray)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -470,11 +429,11 @@ nsCSSRuleProcessor::AppendFontFeatureValuesRules(
|
|||
nsPresContext *aPresContext,
|
||||
nsTArray<nsCSSFontFeatureValuesRule*>& aArray)
|
||||
{
|
||||
ResolvedRuleCascades* resolvedCascade = GetRuleCascade(aPresContext);
|
||||
|
||||
if (resolvedCascade) {
|
||||
for (RuleCascadeData* cascade : resolvedCascade->mOrderedData) {
|
||||
if (!aArray.AppendElements(cascade->mFontFeatureValuesRules)) {
|
||||
if (ResolvedRuleCascades* cascades = GetRuleCascade(aPresContext)) {
|
||||
for (nsCOMPtr<nsIStyleRuleProcessor> processor : cascades->mProcessors) {
|
||||
CascadeLayerRuleProcessor* layerProcessor =
|
||||
static_cast<CascadeLayerRuleProcessor*>(processor.get());
|
||||
if (!layerProcessor->AppendFontFeatureValuesRules(aPresContext, aArray)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -733,6 +692,19 @@ nsCSSRuleProcessor::GetRuleCascade(nsPresContext* aPresContext)
|
|||
return mRuleCascades;
|
||||
}
|
||||
|
||||
/**
|
||||
* This enumerates layers in a sheet and creates child rule processors
|
||||
* for each layer. The child rule processors are created in the order
|
||||
* that the layers are encountered.
|
||||
*/
|
||||
static void
|
||||
CreateChildProcessorsEnumFunc(CascadeEnumData* aLayer, void* aData)
|
||||
{
|
||||
aLayer->AddRules();
|
||||
ResolvedRuleCascades* data = static_cast<ResolvedRuleCascades*>(aData);
|
||||
data->mProcessors.AppendElement(new CascadeLayerRuleProcessor(aLayer));
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSRuleProcessor::RefreshRuleCascade(nsPresContext* aPresContext)
|
||||
{
|
||||
|
|
@ -760,24 +732,26 @@ nsCSSRuleProcessor::RefreshRuleCascade(nsPresContext* aPresContext)
|
|||
mPreviousCacheKey = nullptr;
|
||||
|
||||
if (mSheets.Length() != 0) {
|
||||
nsAutoPtr<ResolvedRuleCascades> resolvedCascade(
|
||||
nsAutoPtr<ResolvedRuleCascades> cascades(
|
||||
new ResolvedRuleCascades(aPresContext->Medium()));
|
||||
CascadeEnumData unlayered(aPresContext,
|
||||
resolvedCascade,
|
||||
mDocumentRules,
|
||||
mDocumentCacheKey,
|
||||
mSheetType,
|
||||
mMustGatherDocumentRules,
|
||||
resolvedCascade->mCacheKey);
|
||||
if (unlayered.mData) {
|
||||
CascadeEnumData* unlayered(new CascadeEnumData(aPresContext,
|
||||
mDocumentRules,
|
||||
mDocumentCacheKey,
|
||||
mSheetType,
|
||||
mMustGatherDocumentRules,
|
||||
cascades->mCacheKey));
|
||||
if (unlayered->mData) {
|
||||
for (uint32_t i = 0; i < mSheets.Length(); ++i) {
|
||||
if (!CascadeSheet(mSheets.ElementAt(i), &unlayered)) {
|
||||
if (!CascadeSheet(mSheets.ElementAt(i), unlayered)) {
|
||||
return; /* out of memory */
|
||||
}
|
||||
}
|
||||
|
||||
unlayered.Flatten();
|
||||
resolvedCascade->mUnlayered = unlayered.mData;
|
||||
// Ensure that the current one is always mRuleCascades.
|
||||
cascades->mNext = mRuleCascades;
|
||||
mRuleCascades = cascades.forget();
|
||||
|
||||
unlayered->EnumerateAllLayers(CreateChildProcessorsEnumFunc, mRuleCascades);
|
||||
|
||||
// mMustGatherDocumentRules controls whether we build mDocumentRules
|
||||
// and mDocumentCacheKey so that they can be used as keys by the
|
||||
|
|
@ -812,10 +786,6 @@ nsCSSRuleProcessor::RefreshRuleCascade(nsPresContext* aPresContext)
|
|||
mDocumentRulesAndCacheKeyValid = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Ensure that the current one is always mRuleCascades.
|
||||
resolvedCascade->mNext = mRuleCascades;
|
||||
mRuleCascades = resolvedCascade.forget();
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue