internal static IEnumerable<CssSelectorGroup> TraverseList(CssSelectorGroup @this) { return @this.TraverseList(i => i.mNext); }
internal CssStyleRule(CssSelectorGroup aSelector, CssDeclaration aDeclaration) { mSelector = aSelector; mDeclaration = aDeclaration; }
internal void AddPseudoClass(CssPseudoClass aType, CssSelectorGroup aSelectorList) { AddPseudoClassInternal(new CssPseudoClassSelector(aType, aSelectorList)); }
internal CssPseudoClassSelector(CssPseudoClass aType, CssSelectorGroup aSelectors) { mType = aType; mSelectors = aSelectors; }
internal bool ParseSelectorList(ref nsCSSSelectorList aListHead, char aStopChar) { nsCSSSelectorList list = null; if (! ParseSelectorGroup(ref list)) { // must have at least one selector group aListHead = null; return false; } Debug.Assert(null != list, "no selector list"); aListHead = list; // After that there must either be a "," or a "{" (the latter if // StopChar is nonzero) nsCSSToken tk = mToken; for (;;) { if (! GetToken(true)) { if (aStopChar == '\0') { return true; } { if (!mSuppressErrors) mReporter.ReportUnexpected("PESelectorListExtraEOF"); }; break; } if (nsCSSTokenType.Symbol == tk.mType) { if (',' == tk.mSymbol) { nsCSSSelectorList newList = null; // Another selector group must follow if (! ParseSelectorGroup(ref newList)) { break; } // add new list to the end of the selector list list.mNext = newList; list = newList; continue; } else if (aStopChar == tk.mSymbol && aStopChar != '\0') { UngetToken(); return true; } } { if (!mSuppressErrors) mReporter.ReportUnexpected("PESelectorListExtra", mToken); }; UngetToken(); break; } aListHead = null; return false; }
internal nsresult ParseSelectorString(string aSelectorString, Uri aURI, // for error reporting uint32_t aLineNumber, // for error reporting ref nsCSSSelectorList aSelectorList) { var scanner = new nsCSSScanner(aSelectorString, aLineNumber); var reporter = new ErrorReporter(scanner, mSheet, mChildLoader, aURI); InitScanner(scanner, reporter, aURI, aURI, null); bool success = ParseSelectorList(ref aSelectorList, '\0'); // We deliberately do not call OUTPUT_ERROR here, because all our // callers map a failure return to a JS exception, and if that JS // exception is caught, people don't want to see parser diagnostics; // see e.g. http://bugs.jquery.com/ticket/7535 // It would be nice to be able to save the parser diagnostics into // the exception, so that if it _isn't_ caught we can report them // along with the usual uncaught-exception message, but we don't // have any way to do that at present; see bug 631621. mReporter.ClearError(); ReleaseScanner(); if (success) { Debug.Assert(aSelectorList != null, "Should have list!"); return nsresult.OK; } Debug.Assert(aSelectorList == null, "Shouldn't have list!"); return nsresult.ERROR_DOM_SYNTAX_ERR; }
/** * This is the format for selectors: * operator? [[namespace |]? element_name]? [ ID | class | attrib | pseudo ]* */ internal bool ParseSelector(nsCSSSelectorList aList, char aPrevCombinator) { if (! GetToken(true)) { { if (!mSuppressErrors) mReporter.ReportUnexpected("PESelectorEOF"); }; return false; } nsCSSSelector selector = aList.AddSelector(aPrevCombinator); string pseudoElement = null; nsAtomList pseudoElementArgs = null; nsCSSPseudoElement pseudoElementType = nsCSSPseudoElement.NotPseudoElement; int32_t dataMask = 0; nsSelectorParsingStatus parsingStatus = ParseTypeOrUniversalSelector(ref dataMask, selector, false); while (parsingStatus == nsSelectorParsingStatus.Continue) { if (nsCSSTokenType.ID == mToken.mType) { // #id parsingStatus = ParseIDSelector(ref dataMask, selector); } else if (mToken.IsSymbol('.')) { // .class parsingStatus = ParseClassSelector(ref dataMask, selector); } else if (mToken.IsSymbol(':')) { // :pseudo parsingStatus = ParsePseudoSelector(ref dataMask, selector, false, ref pseudoElement, pseudoElementArgs, ref pseudoElementType); } else if (mToken.IsSymbol('[')) { // [attribute parsingStatus = ParseAttributeSelector(ref dataMask, selector); if (nsSelectorParsingStatus.Error == parsingStatus) { SkipUntil(']'); } } else { // not a selector token, we're done parsingStatus = nsSelectorParsingStatus.Done; UngetToken(); break; } if (parsingStatus != nsSelectorParsingStatus.Continue) { break; } if (! GetToken(false)) { // premature eof is ok (here!) parsingStatus = nsSelectorParsingStatus.Done; break; } } if (parsingStatus == nsSelectorParsingStatus.Error) { return false; } if (dataMask == 0) { if (selector.mNext != null) { { if (!mSuppressErrors) mReporter.ReportUnexpected("PESelectorGroupExtraCombinator"); }; } else { { if (!mSuppressErrors) mReporter.ReportUnexpected("PESelectorGroupNoSelector"); }; } return false; } if (pseudoElementType == nsCSSPseudoElement.AnonBox) { // We got an anonymous box pseudo-element; it must be the only // thing in this selector group. if (selector.mNext != null || !IsUniversalSelector(selector)) { { if (!mSuppressErrors) mReporter.ReportUnexpected("PEAnonBoxNotAlone"); }; return false; } // Rewrite the current selector as this pseudo-element. // It does not contribute to selector weight. { var t = selector.mLowercaseTag; selector.mLowercaseTag = pseudoElement; pseudoElement = t; }; selector.mClassList = pseudoElementArgs; selector.SetPseudoType(pseudoElementType); return true; } aList.mWeight += selector.CalcWeight(); // Pseudo-elements other than anonymous boxes are represented as // direct children ('>' combinator) of the rest of the selector. if (pseudoElement != null) { selector = aList.AddSelector('>'); { var t = selector.mLowercaseTag; selector.mLowercaseTag = pseudoElement; pseudoElement = t; }; selector.mClassList = pseudoElementArgs; selector.SetPseudoType(pseudoElementType); } return true; }
internal bool ParseSelectorGroup(ref nsCSSSelectorList aList) { char combinator = '\0'; var list = new nsCSSSelectorList(); for (;;) { if (!ParseSelector(list, combinator)) { return false; } // Look for a combinator. if (!GetToken(false)) { break; // EOF ok here } combinator = '\0'; if (mToken.mType == nsCSSTokenType.Whitespace) { if (!GetToken(true)) { break; // EOF ok here } combinator = ' '; } if (mToken.mType != nsCSSTokenType.Symbol) { UngetToken(); // not a combinator } else { char symbol = mToken.mSymbol; if (symbol == '+' || symbol == '>' || symbol == '~') { combinator = mToken.mSymbol; } else { UngetToken(); // not a combinator if (symbol == ',' || symbol == '{' || symbol == ')') { break; // end of selector group } } } if (combinator == 0) { { if (!mSuppressErrors) mReporter.ReportUnexpected("PESelectorListExtra", mToken); }; return false; } } aList = list; return true; }
// // Parse the argument of a pseudo-class that has a selector list argument. // Such selector lists cannot contain combinators, but can contain // anything that goes between a pair of combinators. // internal nsSelectorParsingStatus ParsePseudoClassWithSelectorListArg(nsCSSSelector aSelector, nsCSSPseudoClass aType) { var slist = new nsCSSSelectorList(); if (! ParseSelectorList(ref slist, ')')) { return nsSelectorParsingStatus.Error; // our caller calls SkipUntil(')') } // Check that none of the selectors in the list have combinators or // pseudo-elements. for (nsCSSSelectorList l = slist; l != null; l = l.mNext) { nsCSSSelector s = l.mSelectors; if (s.mNext != null || s.IsPseudoElement()) { return nsSelectorParsingStatus.Error; // our caller calls SkipUntil(')') } } // Add the pseudo with the selector list parameter aSelector.AddPseudoClass(aType, slist); // close the parenthesis if (!ExpectSymbol(')', true)) { { if (!mSuppressErrors) mReporter.ReportUnexpected("PEPseudoClassNoClose", mToken); }; return nsSelectorParsingStatus.Error; // our caller calls SkipUntil(')') } return nsSelectorParsingStatus.Continue; }
internal static IEnumerable <CssSelectorGroup> TraverseList(CssSelectorGroup @this) { return(@this.TraverseList(i => i.mNext)); }
internal CssPseudoClassSelector(CssPseudoClass aType, CssSelectorGroup aSelectors) { mType = aType; mSelectors = aSelectors; }
internal void AddPseudoClass(CssPseudoClass aType, CssSelectorGroup aSelectorList) { AddPseudoClassInternal(new CssPseudoClassSelector(aType, aSelectorList)); }
internal CssStyleRule(CssSelectorGroup aSelector, CssDeclaration aDeclaration) { mSelector = aSelector; mDeclaration = aDeclaration; }