Issue #2828 - Part 1: Build and store the array of layer name tokens in the layer at-rules

This commit is contained in:
Francis Dominic Fajardo 2025-07-08 23:46:54 +08:00 • committed by roytam1
commit 53e6317bfb
3 changed files with 92 additions and 41 deletions

View file

@ -5241,8 +5241,11 @@ CSSParserImpl::ParseSupportsConditionTermsAfterOperator(
bool bool
CSSParserImpl::ParseLayerRule(RuleAppendFunc aAppendFunc, void* aProcessData) CSSParserImpl::ParseLayerRule(RuleAppendFunc aAppendFunc, void* aProcessData)
{ {
nsString layerName; nsString name;
nsTArray<nsString>* nameList = new nsTArray<nsString>(); nsTArray<nsString> path;
nsTArray<nsString> nameList;
nsTArray<nsTArray<nsString>> pathList;
uint32_t linenum, colnum; uint32_t linenum, colnum;
if (!GetNextTokenLocation(true, &linenum, &colnum)) { if (!GetNextTokenLocation(true, &linenum, &colnum)) {
@ -5258,8 +5261,8 @@ CSSParserImpl::ParseLayerRule(RuleAppendFunc aAppendFunc, void* aProcessData)
// followed by a "{", which indicates an anonymous layer. // followed by a "{", which indicates an anonymous layer.
bool isStatement = false; bool isStatement = false;
if (tk->mType == eCSSToken_Ident) { if (tk->mType == eCSSToken_Ident) {
nsString* currentName = new nsString(); name.Assign(tk->mIdent);
currentName->Assign(tk->mIdent); path.AppendElement(tk->mIdent);
bool parsing = true; bool parsing = true;
bool expectIdent = false; bool expectIdent = false;
@ -5272,49 +5275,40 @@ CSSParserImpl::ParseLayerRule(RuleAppendFunc aAppendFunc, void* aProcessData)
case eCSSToken_Symbol: { case eCSSToken_Symbol: {
if ('.' == tk->mSymbol) { if ('.' == tk->mSymbol) {
expectIdent = true; expectIdent = true;
if (!currentName->IsEmpty()) { if (!name.IsEmpty()) {
currentName->Append(tk->mSymbol); name.Append(tk->mSymbol);
continue; continue;
} }
parsing = false; parsing = false;
break; break;
} else if (',' == tk->mSymbol) { } else if (',' == tk->mSymbol || ';' == tk->mSymbol || '{' == tk->mSymbol) {
if (expectIdent) { if (expectIdent) {
parsing = false; parsing = false;
break; break;
} }
nameList->AppendElement(*currentName); nameList.AppendElement(name);
currentName = new nsString(); pathList.AppendElement(path);
if ('{' == tk->mSymbol) {
if (nameList.Length() > 1) {
return false;
}
parsing = false;
break;
} else if (';' == tk->mSymbol) {
isStatement = true;
parsing = false;
break;
}
name.Truncate();
path.Clear();
expectIdent = true; expectIdent = true;
continue; continue;
} else if (';' == tk->mSymbol) {
if (expectIdent) {
parsing = false;
break;
}
nameList->AppendElement(*currentName);
currentName = new nsString();
isStatement = true;
parsing = false;
break;
} else if ('{' == tk->mSymbol) {
if (expectIdent) {
parsing = false;
break;
}
nameList->AppendElement(*currentName);
uint32_t nameListLength = nameList->Length();
if (nameListLength == 0 || nameListLength > 1) {
return false;
}
layerName.Assign(nameList->ElementAt(0));
parsing = false;
break;
} }
} }
case eCSSToken_Ident: { case eCSSToken_Ident: {
expectIdent = false; expectIdent = false;
currentName->Append(tk->mIdent); name.Append(tk->mIdent);
path.AppendElement(tk->mIdent);
break; break;
} }
default: { default: {
@ -5326,22 +5320,26 @@ CSSParserImpl::ParseLayerRule(RuleAppendFunc aAppendFunc, void* aProcessData)
if (expectIdent) { if (expectIdent) {
UngetToken(); UngetToken();
return false; return false;
} }
} else if (tk->mType == eCSSToken_Symbol && '{' != tk->mSymbol) { } else if (tk->mType == eCSSToken_Symbol) {
UngetToken(); if ('{' != tk->mSymbol) {
UngetToken();
return false;
}
} else {
return false; return false;
} }
if (isStatement) { if (isStatement) {
RefPtr<CSSLayerStatementRule> rule = RefPtr<CSSLayerStatementRule> rule =
new CSSLayerStatementRule(*nameList, linenum, colnum); new CSSLayerStatementRule(nameList, pathList, linenum, colnum);
(*aAppendFunc)(rule, aProcessData); (*aAppendFunc)(rule, aProcessData);
return true; return true;
} }
UngetToken(); UngetToken();
RefPtr<css::GroupRule> rule = RefPtr<css::GroupRule> rule =
new CSSLayerBlockRule(layerName, linenum, colnum); new CSSLayerBlockRule(name, path, linenum, colnum);
return ParseGroupRule(rule, aAppendFunc, aProcessData); return ParseGroupRule(rule, aAppendFunc, aProcessData);
} }

View file

@ -3372,15 +3372,18 @@ namespace mozilla {
CSSLayerStatementRule::CSSLayerStatementRule( CSSLayerStatementRule::CSSLayerStatementRule(
const nsTArray<nsString>& aNameList, const nsTArray<nsString>& aNameList,
const nsTArray<nsTArray<nsString>>& aPathList,
uint32_t aLineNumber, uint32_t aColumnNumber) uint32_t aLineNumber, uint32_t aColumnNumber)
: Rule(aLineNumber, aColumnNumber) : Rule(aLineNumber, aColumnNumber)
, mNameList(aNameList) , mNameList(aNameList)
, mPathList(aPathList)
{ {
} }
CSSLayerStatementRule::CSSLayerStatementRule(const CSSLayerStatementRule& aCopy) CSSLayerStatementRule::CSSLayerStatementRule(const CSSLayerStatementRule& aCopy)
: Rule(aCopy) : Rule(aCopy)
, mNameList(aCopy.mNameList) , mNameList(aCopy.mNameList)
, mPathList(aCopy.mPathList)
{ {
} }
@ -3407,6 +3410,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(CSSLayerStatementRule)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CSSLayerStatementRule) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CSSLayerStatementRule)
tmp->mNameList.Clear(); tmp->mNameList.Clear();
tmp->mPathList.Clear();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSLayerStatementRule, mozilla::css::Rule) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSLayerStatementRule, mozilla::css::Rule)
@ -3458,10 +3462,28 @@ CSSLayerStatementRule::GetNameList(nsTArray<nsString>& aResult)
aResult = mNameList; aResult = mNameList;
} }
void
CSSLayerStatementRule::GetPathList(nsTArray<nsTArray<nsString>>& aResult)
{
aResult = mPathList;
}
/* virtual */ size_t /* virtual */ size_t
CSSLayerStatementRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const CSSLayerStatementRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{ {
return aMallocSizeOf(this); size_t n = aMallocSizeOf(this);
n += mNameList.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (const nsString& s : mNameList) {
n += s.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
n += mPathList.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (const nsTArray<nsString>& inner : mPathList) {
n += inner.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (const nsString& str : inner) {
n += str.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
}
return n;
} }
/* virtual */ JSObject* /* virtual */ JSObject*
@ -3477,9 +3499,11 @@ CSSLayerStatementRule::WrapObject(JSContext* aCx,
// //
CSSLayerBlockRule::CSSLayerBlockRule(const nsString& aName, CSSLayerBlockRule::CSSLayerBlockRule(const nsString& aName,
const nsTArray<nsString>& aPath,
uint32_t aLineNumber, uint32_t aColumnNumber) uint32_t aLineNumber, uint32_t aColumnNumber)
: css::GroupRule(aLineNumber, aColumnNumber) : css::GroupRule(aLineNumber, aColumnNumber)
, mName(aName) , mName(aName)
, mPath(aPath)
{ {
} }
@ -3490,6 +3514,7 @@ CSSLayerBlockRule::~CSSLayerBlockRule()
CSSLayerBlockRule::CSSLayerBlockRule(const CSSLayerBlockRule& aCopy) CSSLayerBlockRule::CSSLayerBlockRule(const CSSLayerBlockRule& aCopy)
: css::GroupRule(aCopy) : css::GroupRule(aCopy)
, mName(aCopy.mName) , mName(aCopy.mName)
, mPath(aCopy.mPath)
{ {
} }
@ -3522,15 +3547,32 @@ CSSLayerBlockRule::UseForPresentation(nsPresContext* aPresContext,
return true; return true;
} }
NS_IMPL_ADDREF_INHERITED(CSSLayerBlockRule, css::GroupRule) void
NS_IMPL_RELEASE_INHERITED(CSSLayerBlockRule, css::GroupRule) CSSLayerBlockRule::GetPath(nsTArray<nsString>& aResult)
{
aResult = mPath;
}
NS_IMPL_ADDREF_INHERITED(CSSLayerBlockRule, GroupRule)
NS_IMPL_RELEASE_INHERITED(CSSLayerBlockRule, GroupRule)
// QueryInterface implementation for CSSLayerBlockRule // QueryInterface implementation for CSSLayerBlockRule
NS_INTERFACE_MAP_BEGIN(CSSLayerBlockRule) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSLayerBlockRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule) NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSLayerBlockRule) NS_INTERFACE_MAP_ENTRY(nsIDOMCSSLayerBlockRule)
NS_INTERFACE_MAP_END_INHERITING(GroupRule) NS_INTERFACE_MAP_END_INHERITING(GroupRule)
NS_IMPL_CYCLE_COLLECTION_CLASS(CSSLayerBlockRule)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSLayerBlockRule,
GroupRule)
tmp->mPath.Clear();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSLayerBlockRule,
GroupRule)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
uint16_t uint16_t
CSSLayerBlockRule::Type() const CSSLayerBlockRule::Type() const
{ {
@ -3566,9 +3608,9 @@ CSSLayerBlockRule::DeleteRule(uint32_t aIndex)
// nsIDOMCSSLayerBlockRule methods // nsIDOMCSSLayerBlockRule methods
NS_IMETHODIMP NS_IMETHODIMP
CSSLayerBlockRule::GetName(nsAString& aConditionText) CSSLayerBlockRule::GetName(nsAString& aLayerName)
{ {
aConditionText.Assign(mName); aLayerName.Assign(mName);
return NS_OK; return NS_OK;
} }
@ -3578,6 +3620,10 @@ CSSLayerBlockRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
size_t n = aMallocSizeOf(this); size_t n = aMallocSizeOf(this);
n += css::GroupRule::SizeOfExcludingThis(aMallocSizeOf); n += css::GroupRule::SizeOfExcludingThis(aMallocSizeOf);
n += mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf); n += mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
n += mPath.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (const nsString& s : mPath) {
n += s.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
return n; return n;
} }

View file

@ -746,6 +746,7 @@ class CSSLayerStatementRule final : public css::Rule,
{ {
public: public:
CSSLayerStatementRule(const nsTArray<nsString>& aNameList, CSSLayerStatementRule(const nsTArray<nsString>& aNameList,
const nsTArray<nsTArray<nsString>>& aPathList,
uint32_t aLineNumber, uint32_t aColumnNumber); uint32_t aLineNumber, uint32_t aColumnNumber);
CSSLayerStatementRule(const CSSLayerStatementRule& aCopy); CSSLayerStatementRule(const CSSLayerStatementRule& aCopy);
@ -768,6 +769,7 @@ public:
uint16_t Type() const override; uint16_t Type() const override;
void GetCssTextImpl(nsAString& aCssText) const override; void GetCssTextImpl(nsAString& aCssText) const override;
void GetNameList(nsTArray<nsString>& aResult); void GetNameList(nsTArray<nsString>& aResult);
void GetPathList(nsTArray<nsTArray<nsString>>& aResult);
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override; virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
@ -777,6 +779,7 @@ protected:
virtual ~CSSLayerStatementRule(); virtual ~CSSLayerStatementRule();
nsTArray<nsString> mNameList; nsTArray<nsString> mNameList;
nsTArray<nsTArray<nsString>> mPathList;
}; };
class CSSLayerBlockRule final : public css::GroupRule, class CSSLayerBlockRule final : public css::GroupRule,
@ -784,6 +787,7 @@ class CSSLayerBlockRule final : public css::GroupRule,
{ {
public: public:
CSSLayerBlockRule(const nsString& aName, CSSLayerBlockRule(const nsString& aName,
const nsTArray<nsString>& aPath,
uint32_t aLineNumber, uint32_t aColumnNumber); uint32_t aLineNumber, uint32_t aColumnNumber);
CSSLayerBlockRule(const CSSLayerBlockRule& aCopy); CSSLayerBlockRule(const CSSLayerBlockRule& aCopy);
@ -796,7 +800,9 @@ public:
virtual already_AddRefed<mozilla::css::Rule> Clone() const override; virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
virtual bool UseForPresentation(nsPresContext* aPresContext, virtual bool UseForPresentation(nsPresContext* aPresContext,
nsMediaQueryResultCacheKey& aKey) override; nsMediaQueryResultCacheKey& aKey) override;
void GetPath(nsTArray<nsString>& aResult);
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CSSLayerBlockRule, GroupRule)
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
// nsIDOMCSSGroupingRule interface // nsIDOMCSSGroupingRule interface
@ -818,6 +824,7 @@ protected:
virtual ~CSSLayerBlockRule(); virtual ~CSSLayerBlockRule();
nsString mName; nsString mName;
nsTArray<nsString> mPath;
}; };
} // namespace mozilla } // namespace mozilla