mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-24 08:07:30 +09:00
Issue #2691: Implement ParseSupportsSelector
This commit is contained in:
parent
0903dacaa7
commit
8be86514f0
1 changed files with 107 additions and 0 deletions
|
|
@ -755,6 +755,7 @@ protected:
|
||||||
bool ParseSupportsConditionTermsAfterOperator(
|
bool ParseSupportsConditionTermsAfterOperator(
|
||||||
bool& aConditionMet,
|
bool& aConditionMet,
|
||||||
SupportsConditionTermOperator aOperator);
|
SupportsConditionTermOperator aOperator);
|
||||||
|
bool ParseSupportsSelector(bool& aConditionMet);
|
||||||
|
|
||||||
bool ParseCounterStyleRule(RuleAppendFunc aAppendFunc, void* aProcessData);
|
bool ParseCounterStyleRule(RuleAppendFunc aAppendFunc, void* aProcessData);
|
||||||
bool ParseCounterStyleName(nsAString& aName, bool aForDefinition);
|
bool ParseCounterStyleName(nsAString& aName, bool aForDefinition);
|
||||||
|
|
@ -4784,6 +4785,11 @@ CSSParserImpl::ParseSupportsConditionInParens(bool& aConditionMet)
|
||||||
return ParseSupportsMozBoolPrefName(aConditionMet);
|
return ParseSupportsMozBoolPrefName(aConditionMet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mToken.mType == eCSSToken_Function &&
|
||||||
|
mToken.mIdent.LowerCaseEqualsLiteral("selector")) {
|
||||||
|
return ParseSupportsSelector(aConditionMet);
|
||||||
|
}
|
||||||
|
|
||||||
if (mToken.mType == eCSSToken_Function ||
|
if (mToken.mType == eCSSToken_Function ||
|
||||||
mToken.mType == eCSSToken_Bad_URL) {
|
mToken.mType == eCSSToken_Bad_URL) {
|
||||||
if (!SkipUntil(')')) {
|
if (!SkipUntil(')')) {
|
||||||
|
|
@ -4844,6 +4850,105 @@ CSSParserImpl::ParseSupportsMozBoolPrefName(bool& aConditionMet)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// supports_selector
|
||||||
|
// : 'selector(' single_selector ')'
|
||||||
|
// ;
|
||||||
|
bool
|
||||||
|
CSSParserImpl::ParseSupportsSelector(bool& aConditionMet)
|
||||||
|
{
|
||||||
|
aConditionMet = false;
|
||||||
|
|
||||||
|
nsAutoString selectorText;
|
||||||
|
bool foundClosingParen = false;
|
||||||
|
bool hasContent = false;
|
||||||
|
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (!GetToken(true)) {
|
||||||
|
return false; // fail unexpected EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mToken.IsSymbol(')')) {
|
||||||
|
foundClosingParen = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasContent = true;
|
||||||
|
|
||||||
|
bool needSpace = false;
|
||||||
|
if (!selectorText.IsEmpty()) {
|
||||||
|
char16_t lastChar = selectorText.Last();
|
||||||
|
if (lastChar != ':' && lastChar != '.' && lastChar != '#' && lastChar != '[' && lastChar != '(') {
|
||||||
|
needSpace = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mToken.mType == eCSSToken_Ident) {
|
||||||
|
if (needSpace) selectorText.Append(' ');
|
||||||
|
selectorText.Append(mToken.mIdent);
|
||||||
|
|
||||||
|
} else if (mToken.mType == eCSSToken_AtKeyword) {
|
||||||
|
if (needSpace) selectorText.Append(' ');
|
||||||
|
selectorText.Append('@');
|
||||||
|
selectorText.Append(mToken.mIdent);
|
||||||
|
|
||||||
|
} else if (mToken.mType == eCSSToken_Hash) {
|
||||||
|
if (needSpace) selectorText.Append(' ');
|
||||||
|
selectorText.Append('#');
|
||||||
|
selectorText.Append(mToken.mIdent);
|
||||||
|
|
||||||
|
} else if (mToken.mType == eCSSToken_Symbol) {
|
||||||
|
selectorText.Append(mToken.mSymbol);
|
||||||
|
|
||||||
|
} else if (mToken.mType == eCSSToken_String) {
|
||||||
|
if (needSpace) selectorText.Append(' ');
|
||||||
|
selectorText.Append('"');
|
||||||
|
selectorText.Append(mToken.mIdent);
|
||||||
|
selectorText.Append('"');
|
||||||
|
|
||||||
|
} else if (mToken.mType == eCSSToken_Function) {
|
||||||
|
if (needSpace) selectorText.Append(' ');
|
||||||
|
selectorText.Append(mToken.mIdent);
|
||||||
|
selectorText.Append('(');
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (!mToken.mIdent.IsEmpty()) {
|
||||||
|
if (needSpace) selectorText.Append(' ');
|
||||||
|
selectorText.Append(mToken.mIdent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundClosingParen) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasContent) {
|
||||||
|
aConditionMet = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectorText.CompressWhitespace(true, true);
|
||||||
|
|
||||||
|
// basic validation
|
||||||
|
// reject issues like multiple selectors (comma-separated)
|
||||||
|
if (selectorText.FindChar(',') >= 0) {
|
||||||
|
aConditionMet = false;
|
||||||
|
} else if (selectorText.IsEmpty()) {
|
||||||
|
aConditionMet = false;
|
||||||
|
} else {
|
||||||
|
// assume basic selectors, pseudo-elements, and compound selectors to be true
|
||||||
|
aConditionMet = true;
|
||||||
|
|
||||||
|
// special case: reject obviously unsupported pseudo-elements
|
||||||
|
if (selectorText.Find(NS_LITERAL_STRING("::-webkit-")) >= 0) {
|
||||||
|
aConditionMet = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// supports_condition_in_parens_inside_parens
|
// supports_condition_in_parens_inside_parens
|
||||||
// : core_declaration
|
// : core_declaration
|
||||||
// | supports_condition_negation
|
// | supports_condition_negation
|
||||||
|
|
@ -4912,6 +5017,8 @@ CSSParserImpl::ParseSupportsConditionInParensInsideParens(bool& aConditionMet)
|
||||||
ParseSupportsConditionTerms(aConditionMet);
|
ParseSupportsConditionTerms(aConditionMet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// supports_condition_terms
|
// supports_condition_terms
|
||||||
// : S+ 'and' supports_condition_terms_after_operator('and')
|
// : S+ 'and' supports_condition_terms_after_operator('and')
|
||||||
// | S+ 'or' supports_condition_terms_after_operator('or')
|
// | S+ 'or' supports_condition_terms_after_operator('or')
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue