diff options
author | FranklinDM <mrmineshafter17@gmail.com> | 2023-02-21 22:06:49 +0800 |
---|---|---|
committer | FranklinDM <mrmineshafter17@gmail.com> | 2023-02-22 14:00:49 +0800 |
commit | 826464c80b3413729a5c3ed65bc0ad41785cac9d (patch) | |
tree | e71595260052fe0a85044a16964207f218b62659 /layout | |
parent | f17feba05faaaec2c08d86753da046eeffe1ac34 (diff) | |
download | uxp-826464c80b3413729a5c3ed65bc0ad41785cac9d.tar.gz |
Issue #2078 - Follow-up: Propagate combinator restriction to :is()/:where()
Based on spec discussion: https://github.com/w3c/csswg-drafts/issues/5093
Diffstat (limited to 'layout')
-rw-r--r-- | layout/style/nsCSSParser.cpp | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 9bdb202ace..3fc68fe624 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -765,7 +765,8 @@ protected: bool aIsNegated, nsIAtom** aPseudoElement, nsAtomList** aPseudoElementArgs, - CSSPseudoElementType* aPseudoElementType); + CSSPseudoElementType* aPseudoElementType, + bool aDisallowCombinators); nsSelectorParsingStatus ParseAttributeSelector(int32_t& aDataMask, nsCSSSelector& aSelector); @@ -781,7 +782,8 @@ protected: CSSPseudoClassType aType); nsSelectorParsingStatus ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector, - CSSPseudoClassType aType); + CSSPseudoClassType aType, + bool aDisallowCombinators); nsSelectorParsingStatus ParseNegatedSimpleSelector(int32_t& aDataMask, nsCSSSelector& aSelector); @@ -790,12 +792,15 @@ protected: // aStopChar. Otherwise, it's done when we hit EOF. bool ParseSelectorList(nsCSSSelectorList*& aListHead, char16_t aStopChar, - bool aIsForgiving); + bool aIsForgiving, + bool aDisallowCombinators); bool ParseSelectorGroup(nsCSSSelectorList*& aListHead, - bool aIsForgiving); + bool aIsForgiving, + bool aDisallowCombinators); bool ParseSelector(nsCSSSelectorList* aList, char16_t aPrevCombinator, - bool aIsForgiving); + bool aIsForgiving, + bool aDisallowCombinators); enum { eParseDeclaration_InBraces = 1 << 0, @@ -2324,7 +2329,7 @@ CSSParserImpl::ParseSelectorString(const nsSubstring& aSelectorString, css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI); InitScanner(scanner, reporter, aURI, aURI, nullptr); - bool success = ParseSelectorList(*aSelectorList, char16_t(0), false); + bool success = ParseSelectorList(*aSelectorList, char16_t(0), false, false); // We deliberately do not call OUTPUT_ERROR here, because all our // callers map a failure return to a JS exception, and if that JS @@ -5413,7 +5418,7 @@ CSSParserImpl::ParseRuleSet(RuleAppendFunc aAppendFunc, void* aData, nsCSSSelectorList* slist = nullptr; uint32_t linenum, colnum; if (!GetNextTokenLocation(true, &linenum, &colnum) || - !ParseSelectorList(slist, char16_t('{'), false)) { + !ParseSelectorList(slist, char16_t('{'), false, false)) { REPORT_UNEXPECTED(PEBadSelectorRSIgnored); OUTPUT_ERROR(); SkipRuleSet(aInsideBraces); @@ -5450,10 +5455,11 @@ CSSParserImpl::ParseRuleSet(RuleAppendFunc aAppendFunc, void* aData, bool CSSParserImpl::ParseSelectorList(nsCSSSelectorList*& aListHead, char16_t aStopChar, - bool aIsForgiving) + bool aIsForgiving, + bool aDisallowCombinators) { nsCSSSelectorList* list = nullptr; - if (! ParseSelectorGroup(list, aIsForgiving)) { + if (! ParseSelectorGroup(list, aIsForgiving, aDisallowCombinators)) { if (aIsForgiving) { // Initialize to an empty list if the first selector group was invalid // and we're a forgiving selector list. @@ -5484,7 +5490,7 @@ CSSParserImpl::ParseSelectorList(nsCSSSelectorList*& aListHead, if (',' == tk->mSymbol) { nsCSSSelectorList* newList = nullptr; // Another selector group must follow - if (! ParseSelectorGroup(newList, aIsForgiving)) { + if (! ParseSelectorGroup(newList, aIsForgiving, aDisallowCombinators)) { // Ignore invalid selectors if we're a forgiving selector list. if (aIsForgiving) { continue; @@ -5532,13 +5538,13 @@ static bool IsUniversalSelector(const nsCSSSelector& aSelector) } bool -CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList, bool aIsForgiving) +CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList, bool aIsForgiving, bool aDisallowCombinators) { char16_t combinator = 0; nsAutoPtr<nsCSSSelectorList> list(new nsCSSSelectorList()); for (;;) { - if (!ParseSelector(list, combinator, aIsForgiving)) { + if (!ParseSelector(list, combinator, aIsForgiving, aDisallowCombinators)) { return false; } @@ -5573,6 +5579,10 @@ CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList, bool aIsForgiving) REPORT_UNEXPECTED_TOKEN(PESelectorListExtra); return false; } + + if (aIsForgiving && aDisallowCombinators) { + return false; + } } aList = list.forget(); @@ -5995,7 +6005,8 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask, bool aIsNegated, nsIAtom** aPseudoElement, nsAtomList** aPseudoElementArgs, - CSSPseudoElementType* aPseudoElementType) + CSSPseudoElementType* aPseudoElementType, + bool aDisallowCombinators) { NS_ASSERTION(aIsNegated || (aPseudoElement && aPseudoElementArgs), "expected location to store pseudo element"); @@ -6166,7 +6177,8 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask, MOZ_ASSERT(nsCSSPseudoClasses::HasSelectorListArg(pseudoClassType), "unexpected pseudo with function token"); parsingStatus = ParsePseudoClassWithSelectorListArg(aSelector, - pseudoClassType); + pseudoClassType, + aDisallowCombinators); } if (eSelectorParsingStatus_Continue != parsingStatus) { if (eSelectorParsingStatus_Error == parsingStatus) { @@ -6293,7 +6305,8 @@ CSSParserImpl::ParseNegatedSimpleSelector(int32_t& aDataMask, } else if (mToken.IsSymbol(':')) { // :pseudo parsingStatus = ParsePseudoSelector(aDataMask, *newSel, true, - nullptr, nullptr, nullptr); + nullptr, nullptr, nullptr, + false); } else if (mToken.IsSymbol('[')) { // [attribute parsingStatus = ParseAttributeSelector(aDataMask, *newSel); @@ -6535,18 +6548,27 @@ CSSParserImpl::ParsePseudoClassWithNthPairArg(nsCSSSelector& aSelector, // CSSParserImpl::nsSelectorParsingStatus CSSParserImpl::ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector, - CSSPseudoClassType aType) + CSSPseudoClassType aType, + bool aDisallowCombinators) { bool isForgiving = nsCSSPseudoClasses::HasForgivingSelectorListArg(aType); + bool isSingleSelector = + nsCSSPseudoClasses::HasSingleSelectorArg(aType); + + if (isSingleSelector && !aDisallowCombinators) { + aDisallowCombinators = true; + } nsAutoPtr<nsCSSSelectorList> slist; - if (! ParseSelectorList(*getter_Transfers(slist), char16_t(')'), isForgiving)) { + if (! ParseSelectorList(*getter_Transfers(slist), + char16_t(')'), + isForgiving, + aDisallowCombinators)) { return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')') } - if (nsCSSPseudoClasses::HasSingleSelectorArg(aType) && - slist->mNext) { + if (isSingleSelector && slist->mNext) { return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')') } @@ -6584,7 +6606,8 @@ CSSParserImpl::ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector, bool CSSParserImpl::ParseSelector(nsCSSSelectorList* aList, char16_t aPrevCombinator, - bool aIsForgiving) + bool aIsForgiving, + bool aDisallowCombinators) { if (! GetToken(true)) { REPORT_UNEXPECTED_EOF(PESelectorEOF); @@ -6605,7 +6628,8 @@ CSSParserImpl::ParseSelector(nsCSSSelectorList* aList, parsingStatus = ParsePseudoSelector(dataMask, *selector, false, getter_AddRefs(pseudoElement), getter_Transfers(pseudoElementArgs), - &pseudoElementType); + &pseudoElementType, + aDisallowCombinators); if (pseudoElement && pseudoElementType != CSSPseudoElementType::AnonBox) { // Pseudo-elements other than anonymous boxes are represented with |