protected virtual void ParseName(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (tokens.CurrentToken.TokenType == CssTokenType.Function && tokens.CurrentToken.Start == Colon.AfterEnd) { if (TextRange.CompareDecoded(tokens.CurrentToken.Start, tokens.CurrentToken.Length, text, "not(", ignoreCase: true)) { Function = itemFactory.CreateSpecific <PseudoFunctionNot>(this); } else if (TextRange.CompareDecoded(tokens.CurrentToken.Start, tokens.CurrentToken.Length, text, "matches(", ignoreCase: true)) { Function = itemFactory.CreateSpecific <PseudoFunctionMatches>(this); } else { Function = itemFactory.CreateSpecific <Function>(this); } Function.Parse(itemFactory, text, tokens); // Function name should be colorizer as pseudo-class Function.Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.PseudoClass); Function.FunctionName.Context = Function.Context; Children.Add(Function); } else { Children.AddParseError(ParseErrorType.PseudoClassNameMissing); } }
public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { UnitType = UnitType.Unknown; if (tokens.CurrentToken.TokenType == CssTokenType.Number) { if (!base.Parse(itemFactory, text, tokens)) { return(false); } } Debug.Assert(tokens.CurrentToken.TokenType == CssTokenType.Units); UnitToken = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.Units); UnitType = UnitHelpers.GetUnitType(text, UnitToken.Start, UnitToken.Length); CssClassifierContextType ct = CssClassifierContextType.Units; switch (UnitType) { case UnitType.Angle: ct = CssClassifierContextType.AngleUnits; break; case UnitType.Frequency: ct = CssClassifierContextType.FrequencyUnits; break; case UnitType.Grid: ct = CssClassifierContextType.GridUnits; break; case UnitType.Length: ct = CssClassifierContextType.LengthUnits; break; case UnitType.Percentage: ct = CssClassifierContextType.PercentUnits; break; case UnitType.Resolution: ct = CssClassifierContextType.ResolutionUnits; break; case UnitType.Time: ct = CssClassifierContextType.TimeUnits; break; case UnitType.Viewport: ct = CssClassifierContextType.ViewUnits; break; } UnitToken.Context = CssClassifierContextCache.FromTypeEnum(ct); return(Children.Count > 0); }
public void ParseItem_ClassifierContextTest() { CssParser p = new CssParser(); StyleSheet s = p.Parse("@media { foo }", false); Assert.IsTrue(s.Children[0].Context.IsDefault()); Assert.IsTrue(((ComplexItem)s.Children[0]).Children[0].Context.IsEqualTo((int)CssClassifierContextType.AtDirectiveName, typeof(CssClassifierContextType))); Assert.IsTrue(s.Children[0] is AtBlockDirective); s.Children[0].Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.PercentUnits); Assert.IsTrue(s.Children[0].Context.IsEqualTo((int)CssClassifierContextType.PercentUnits, typeof(CssClassifierContextType))); Assert.IsTrue(s.Children[0] is AtBlockDirective); }
protected virtual void ParseName(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (tokens.CurrentToken.TokenType == CssTokenType.Function && tokens.CurrentToken.Start == DoubleColon.AfterEnd) { Function = itemFactory.CreateSpecific <Function>(this); Function.Parse(itemFactory, text, tokens); Function.Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.PseudoElement); Children.Add(Function); } else { Children.AddParseError(ParseErrorType.PseudoElementNameMissing); } }
public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.PropertyName); if (tokens.CurrentToken.TokenType == CssTokenType.Asterisk && tokens.Peek(1).TokenType == CssTokenType.Identifier) { Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.CustomPropertyName); Children.AddCurrentAndAdvance(tokens, Context); } if (tokens.CurrentToken.TokenType == CssTokenType.Identifier) { Children.AddCurrentAndAdvance(tokens, Context); } return(Children.Count > 0); }
public void GetClassificationNameTest() { // For every single classifier context, make sure that the name returned by // IClassifierContext.GetClassificationName is correct. int length = (int)CssClassifierContextType.CssClassifierContextTypeCount; for (int i = 0; i < length; i++) { CssClassifierContextType contextType = (CssClassifierContextType)i; IClassifierContext context = CssClassifierContextCache.FromTypeEnum(contextType); // Make sure I got the right thing from the cache Assert.IsNotNull(context); Assert.AreEqual((int)contextType, context.ContextValue); Assert.IsTrue(context.ClassificationName == "Default" || context.ClassificationName == "Css" + contextType.ToString()); } }
internal virtual bool ParseInFunction(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (ItemName.IsAtItemName(tokens)) { ItemName name = itemFactory.CreateSpecific <ItemName>(this); if (name.Parse(itemFactory, text, tokens)) { name.Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.ElementTagName); Name = name; Children.Add(name); } } if (Name == null || Name.AfterEnd == tokens.CurrentToken.Start) { while (!IsAtSelectorTerminator(tokens) && tokens.CurrentToken.TokenType != CssTokenType.CloseFunctionBrace) { ParseItem childItem = CreateNextAtomicPart(itemFactory, text, tokens); if (childItem == null || !childItem.Parse(itemFactory, text, tokens)) { childItem = UnknownItem.ParseUnknown(this, itemFactory, text, tokens, ParseErrorType.PseudoFunctionSelectorExpected); } else { SubSelectors.Add(childItem); } Children.Add(childItem); if (tokens.IsWhiteSpaceBeforeCurrentToken()) { break; } } } return(Children.Count > 0); }
public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { ParseAtAndKeyword(itemFactory, text, tokens); if (tokens.CurrentToken.TokenType == CssTokenType.Identifier) { Namespace = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.ItemNamespace); } if (tokens.CurrentToken.IsString()) { String = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.String); } else if (tokens.CurrentToken.TokenType == CssTokenType.Url) { Url = new UrlItem(); if (Url.Parse(itemFactory, text, tokens)) { Url.Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.UrlString); Children.Add(Url); } else { Url = null; } } if (String == null && Url == null) { Children.AddParseError(ParseErrorType.UrlNamespaceMissing); } CheckSemicolon(tokens); return(Children.Count > 0); }
protected virtual void ParseUrl(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (tokens.CurrentToken.IsString()) { FileNames.Add(Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.ImportUrl)); } else if (tokens.CurrentToken.TokenType == CssTokenType.Url) { UrlItem url = new UrlItem { Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.ImportUrl) }; if (url.Parse(itemFactory, text, tokens)) { FileNames.Add(url); Children.Add(url); } } else { Children.AddParseError(ParseErrorType.UrlImportMissing); } }
public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (tokens.CurrentToken.TokenType != CssTokenType.OpenSquareBracket) { return(false); } // Collect each piece of "[ name = value ]", any of which could be missing after the '[' OpenBracket = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.SquareBracket); if (ItemName.IsAtItemName(tokens)) { AttributeName = itemFactory.CreateSpecific <ItemName>(this); AttributeName.Parse(itemFactory, text, tokens); AttributeName.Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.ElementAttribute); Children.Add(AttributeName); } else { OpenBracket.AddParseError(ParseErrorType.AttributeSelectorElementMissing, ParseErrorLocation.AfterItem); } switch (tokens.CurrentToken.TokenType) { case CssTokenType.BeginsWith: // ^= case CssTokenType.EndsWith: // $= case CssTokenType.OneOf: // ~= case CssTokenType.ListBeginsWith: // |= case CssTokenType.ContainsString: // *= case CssTokenType.Equals: // = Operation = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.SelectorOperator); break; } if (tokens.CurrentToken.TokenType == CssTokenType.Identifier) { AttributeValue = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.ElementAttributeValue); } else if (tokens.CurrentToken.IsString()) { AttributeValue = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.ElementAttributeValue); } if (AttributeValue != null && Operation == null) { AttributeValue.AddParseError(ParseErrorType.AttributeSelectorOperationMissing, ParseErrorLocation.BeforeItem); } else if (AttributeValue == null && Operation != null) { Operation.AddParseError(ParseErrorType.AttributeSelectorValueMissing, ParseErrorLocation.AfterItem); } if (AttributeValue != null && tokens.CurrentToken.TokenType == CssTokenType.Identifier) { OperationModifier = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.SelectorOperator); if (OperationModifier.Length != 1 || text[OperationModifier.Start] != 'i') { OperationModifier.AddParseError(ParseErrorType.UnexpectedToken, ParseErrorLocation.WholeItem); } } if (tokens.CurrentToken.TokenType == CssTokenType.CloseSquareBracket) { CloseBracket = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.SquareBracket); } else { AddParseError(ParseErrorType.AttributeSelectorCloseBracketMissing, ParseErrorLocation.AfterItem); } return(Children.Count > 0); }
internal TokenItem AddCurrentAndAdvance(TokenStream tokens, CssClassifierContextType ct) { return(AddCurrentAndAdvance(tokens, CssClassifierContextCache.FromTypeEnum(ct))); }
public Selector() { Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.Selector); SimpleSelectors = new SortedRangeList <SimpleSelector>(); }
public Function() { Arguments = new ParseItemList(); Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.FunctionName); }
protected virtual IClassifierContext GetArgumentContext(int argumentNumber) { return(CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.FunctionArgument)); }
public Declaration() { Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.PropertyDeclaration); Values = new ParseItemList(); }
public FunctionColor() { // The function type gets updated during parsing ColorFunction = ColorFunctionType.None; Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.FunctionColor); }
internal TokenItem(CssToken token, CssClassifierContextType context) : this(token, CssClassifierContextCache.FromTypeEnum(context)) { }
public PseudoElementSelector() { Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.PseudoElement); }
internal KeyFramesSelector() { SelectorType = KeyFrameSelectorType.Unknown; Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.Selector); }
public PseudoClassFunctionSelector() { Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.PseudoClass); }
public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { bool hasSubject = false; // Allow a bang before the tag name. while (tokens.CurrentToken.TokenType == CssTokenType.Bang) { ParseItem item = itemFactory.Create <SubjectSelector>(this); if (item.Parse(itemFactory, text, tokens)) { Children.Add(item); if (hasSubject) { item.AddParseError(ParseErrorType.UnexpectedBangInSelector, ParseErrorLocation.WholeItem); } hasSubject = true; } if (tokens.IsWhiteSpaceBeforeCurrentToken()) { break; } } if (ItemName.IsAtItemName(tokens)) { ItemName name = itemFactory.CreateSpecific <ItemName>(this); if (name.Parse(itemFactory, text, tokens)) { name.Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.ElementTagName); Name = name; Children.Add(name); } } ParseItem lastItem = (Children.Count > 0) ? Children[Children.Count - 1] : null; // Only continue parsing the simple selector if the name touches the next token. if (lastItem == null || lastItem.AfterEnd == tokens.CurrentToken.Start) { bool addedErrorItem = false; while (!IsAtSelectorTerminator(tokens)) { ParseItem pi = CreateNextAtomicPart(itemFactory, text, tokens); if (pi == null) { // Only treat the first bad token as an error (don't need more than one in a row) if (addedErrorItem) { pi = UnknownItem.ParseUnknown(this, itemFactory, text, tokens); } else { pi = UnknownItem.ParseUnknown(this, itemFactory, text, tokens, ParseErrorType.SimpleSelectorExpected); addedErrorItem = true; } } else if (!pi.Parse(itemFactory, text, tokens)) { break; } if (pi is SubjectSelector) { if (hasSubject) { pi.AddParseError(ParseErrorType.UnexpectedBangInSelector, ParseErrorLocation.WholeItem); } hasSubject = true; } SubSelectors.Add(pi); Children.Add(pi); if (tokens.IsWhiteSpaceBeforeCurrentToken()) { break; } } } if (IsAtSelectorCombineOperator(text, tokens)) { ParseSelectorCombineOperator(itemFactory, text, tokens); if (Name == null && SelectorCombineOperator != null & SubSelectors.Count == 0 && !CanStartWithCombineOperator(SelectorCombineOperator)) { SelectorCombineOperator.AddParseError(ParseErrorType.SelectorBeforeCombineOperatorMissing, ParseErrorLocation.BeforeItem); } } return(Children.Count > 0); }
public MediaQuery() { Expressions = new SortedRangeList <MediaExpression>(); Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.MediaQuery); }