Пример #1
0
 private static void AssertNextToken(CssScanner lex, CssTokenType type, Func<CssToken, bool> condition)
 {
     var token = new CssToken();
     Assert.IsTrue(lex.Next(token, true), "Unexpected EOF");
     Assert.AreEqual(type, token.mType);
     Assert.IsTrue(condition(token), "Condition for token {0} failed".Fmt(token.mType));
 }
Пример #2
0
		public CssToken(string value, CssTokenType type, int line, int col)
		{
			this.value = value;
			this.type = type;
			this.col = col;
			this.line = line;
		}
Пример #3
0
        /// <summary>
        /// 4.4.19. URL-single-quoted state
        /// </summary>
        CssToken UrlSQ(CssTokenType type)
        {
            while (true)
            {
                var current = Next;

                if (current.IsLineBreak())
                {
                    RaiseErrorOccurred(ErrorCode.LineBreakUnexpected);
                    return(UrlBad(type));
                }
                else if (Specification.EndOfFile == current)
                {
                    return(CssStringToken.Url(type, FlushBuffer()));
                }
                else if (current == Specification.SingleQuote)
                {
                    return(UrlEnd(type));
                }
                else if (current == Specification.ReverseSolidus)
                {
                    current = Next;

                    if (current == Specification.EndOfFile)
                    {
                        Back(2);
                        RaiseErrorOccurred(ErrorCode.EOF);
                        return(CssStringToken.Url(type, FlushBuffer(), true));
                    }
                    else if (current.IsLineBreak())
                    {
                        _stringBuffer.AppendLine();
                    }
                    else
                    {
                        _stringBuffer.Append(ConsumeEscape(current));
                    }
                }
                else
                {
                    _stringBuffer.Append(current);
                }
            }
        }
Пример #4
0
        protected void AddToken(CssTokenType type, int start, int length)
        {
            CssToken token = new CssToken(type, start, length);

            Tokens.Add(token);
#if DEBUG
            token.DebugText = (type != CssTokenType.EndOfFile)
                ? CS.TextProvider.GetText(start, length)
                : "EOF";

            if (type != CssTokenType.WhiteSpace && token.DebugText.Length > 0)
            {
                // Tokens must not have whitespace at either end (that can break incremental tokenizing)
                Debug.Assert(
                    !TextHelper.IsWhiteSpace(token.DebugText[0]) &&
                    !TextHelper.IsWhiteSpace(token.DebugText[token.DebugText.Length - 1]));
            }
#endif
        }
Пример #5
0
        /// <summary>
        /// 4.4.22. Bad URL state
        /// </summary>
        CssToken UrlBad(CssTokenType type)
        {
            while (true)
            {
                var current = GetNext();

                if (current == Symbols.EndOfFile)
                {
                    RaiseErrorOccurred(ErrorCode.EOF);
                    return(CssStringToken.Url(type, FlushBuffer(), true));
                }
                else if (current == Symbols.RoundBracketClose)
                {
                    return(CssStringToken.Url(type, FlushBuffer(), true));
                }
                else if (IsValidEscape(current))
                {
                    current = GetNext();
                    _stringBuffer.Append(ConsumeEscape(current));
                }
            }
        }
Пример #6
0
        /// <summary>
        /// 4.4.22. Bad URL state
        /// </summary>
        CssToken UrlBad(Char current, CssTokenType type)
        {
            while (true)
            {
                if (current == Specification.EndOfFile)
                {
                    RaiseErrorOccurred(ErrorCode.EOF);
                    return(CssStringToken.Url(type, FlushBuffer(), true));
                }
                else if (current == Specification.RoundBracketClose)
                {
                    return(CssStringToken.Url(type, FlushBuffer(), true));
                }
                else if (IsValidEscape(current))
                {
                    current = _src.Next;
                    _stringBuffer.Append(ConsumeEscape(current));
                }

                current = _src.Next;
            }
        }
Пример #7
0
        void FillMediaList(MediaList list, CssTokenType end, ref CssToken token)
        {
            if (token.Type == end)
            {
                return;
            }

            while (token.Type != CssTokenType.Eof)
            {
                CreateNewNode();
                var medium = CloseNode(CreateMedium(ref token));

                if (medium != null)
                {
                    list.Add(medium);
                }

                if (token.Type != CssTokenType.Comma)
                {
                    break;
                }

                token = NextToken();
                CollectTrivia(ref token);
            }

            if (token.Type == end && list.Length > 0)
            {
                return;
            }

            list.Clear();
            list.Add(new CssMedium
            {
                IsInverse = true,
                Type      = Keywords.All
            });
        }
Пример #8
0
        /// <summary>
        /// 4.4.21. URL-unquoted state
        /// </summary>
        CssToken UrlUQ(Char current, CssTokenType type)
        {
            while (true)
            {
                if (current.IsSpaceCharacter())
                {
                    return(UrlEnd(type));
                }
                else if (current == Symbols.RoundBracketClose || current == Symbols.EndOfFile)
                {
                    return(NewUrl(type, FlushBuffer()));
                }
                else if (current == Symbols.DoubleQuote || current == Symbols.SingleQuote || current == Symbols.RoundBracketOpen || current.IsNonPrintable())
                {
                    RaiseErrorOccurred(CssParseError.InvalidCharacter);
                    return(UrlBad(type));
                }
                else if (current == Symbols.ReverseSolidus)
                {
                    if (IsValidEscape(current))
                    {
                        current = GetNext();
                        _stringBuffer.Append(ConsumeEscape(current));
                    }
                    else
                    {
                        RaiseErrorOccurred(CssParseError.InvalidCharacter);
                        return(UrlBad(type));
                    }
                }
                else
                {
                    _stringBuffer.Append(current);
                }

                current = GetNext();
            }
        }
Пример #9
0
        /// <summary>
        /// 4.4.21. URL-unquoted state
        /// </summary>
        CssToken UrlUQ(Char current, CssTokenType type)
        {
            while (true)
            {
                if (current.IsSpaceCharacter())
                {
                    return(UrlEnd(type));
                }
                else if (current == Specification.RoundBracketClose || current == Specification.EndOfFile)
                {
                    return(CssStringToken.Url(type, FlushBuffer()));
                }
                else if (current == Specification.DoubleQuote || current == Specification.SingleQuote || current == Specification.RoundBracketOpen || current.IsNonPrintable())
                {
                    RaiseErrorOccurred(ErrorCode.InvalidCharacter);
                    return(UrlBad(type));
                }
                else if (current == Specification.ReverseSolidus)
                {
                    if (IsValidEscape(current))
                    {
                        current = Next;
                        _stringBuffer.Append(ConsumeEscape(current));
                    }
                    else
                    {
                        RaiseErrorOccurred(ErrorCode.InvalidCharacter);
                        return(UrlBad(type));
                    }
                }
                else
                {
                    _stringBuffer.Append(current);
                }

                current = Next;
            }
        }
Пример #10
0
        /// <summary>
        /// Appends media labels from the given source to the medialist.
        /// </summary>
        /// <param name="source">The token iterator.</param>
        /// <param name="media">The medialist to append to.</param>
        /// <param name="endToken">The optional token type to finish appending to the list.</param>
        void AppendMediaList(IEnumerator <CssToken> source, MediaList media, CssTokenType endToken = CssTokenType.Semicolon)
        {
            do
            {
                if (source.Current.Type == CssTokenType.Whitespace)
                {
                    continue;
                }
                else if (source.Current.Type == endToken)
                {
                    break;
                }

                do
                {
                    if (source.Current.Type == CssTokenType.Comma || source.Current.Type == endToken)
                    {
                        break;
                    }
                    else if (source.Current.Type == CssTokenType.Whitespace)
                    {
                        buffer.Append(' ');
                    }
                    else
                    {
                        buffer.Append(source.Current.ToValue());
                    }
                }while (source.MoveNext());

                media.AppendMedium(buffer.ToString());
                buffer.Clear();

                if (source.Current.Type == endToken)
                {
                    break;
                }
            }while (source.MoveNext());
        }
Пример #11
0
        // two more bools can fit before enum flags should be used

        internal CssToken(CssTokenType tokenType, int start, int length)
        {
            TokenType = tokenType;
            Start     = start;
            Length    = length;

            switch (TokenType)
            {
            case CssTokenType.CloseCComment:
            case CssTokenType.CommentText:
                IsComment    = true;
                IsChildToken = true;
                break;

            case CssTokenType.CloseHtmlComment:
            case CssTokenType.OpenCComment:
            case CssTokenType.OpenHtmlComment:
            case CssTokenType.SingleLineComment:
            case CssTokenType.SingleTokenComment:
                IsComment = true;
                break;
            }
        }
Пример #12
0
        /// <summary>
        /// 4.4.17. URL state
        /// </summary>
        CssToken UrlStart(CssTokenType type)
        {
            var current = SkipSpaces();

            switch (current)
            {
            case Symbols.EndOfFile:
                RaiseErrorOccurred(CssParseError.EOF);
                return(NewUrl(type, String.Empty, true));

            case Symbols.DoubleQuote:
                return(UrlDQ(type));

            case Symbols.SingleQuote:
                return(UrlSQ(type));

            case Symbols.RoundBracketClose:
                return(NewUrl(type, String.Empty, false));

            default:
                return(UrlUQ(current, type));
            }
        }
Пример #13
0
        /// <summary>
        /// 4.4.17. URL state
        /// </summary>
        CssToken UrlStart(CssTokenType type)
        {
            var current = SkipSpaces();

            switch (current)
            {
            case Symbols.EndOfFile:
                RaiseErrorOccurred(ErrorCode.EOF);
                return(CssStringToken.Url(type, String.Empty, true));

            case Symbols.DoubleQuote:
                return(UrlDQ(type));

            case Symbols.SingleQuote:
                return(UrlSQ(type));

            case ')':
                return(CssStringToken.Url(type, String.Empty, false));

            default:
                return(UrlUQ(current, type));
            }
        }
Пример #14
0
        void FillMediaList(MediaList list, CssTokenType end, ref CssToken token)
        {
            _nodes.Push(list);

            if (token.Type != end)
            {
                while (token.Type != CssTokenType.EndOfFile)
                {
                    var medium = CreateMedium(ref token);

                    if (medium != null)
                    {
                        list.AppendChild(medium);
                    }

                    if (token.Type != CssTokenType.Comma)
                    {
                        break;
                    }

                    token = NextToken();
                    CollectTrivia(ref token);
                }

                if (token.Type != end || list.Length == 0)
                {
                    list.Clear();
                    list.AppendChild(new CssMedium
                    {
                        IsInverse = true,
                        Type      = Keywords.All
                    });
                }
            }

            _nodes.Pop();
        }
Пример #15
0
        /// <summary>
        /// Before any medium has been found for the @media or @import rule.
        /// </summary>
        void FillMediaList(MediaList list, CssTokenType end, ref CssToken token)
        {
            if (token.Type == end)
            {
                return;
            }

            while (token.Type != CssTokenType.Eof)
            {
                var medium = CreateMedium(ref token);

                if (medium != null)
                {
                    list.Add(medium);
                }

                if (token.Type != CssTokenType.Comma)
                {
                    break;
                }

                token = _tokenizer.Get();
            }

            if (token.Type == end && list.Length > 0)
            {
                return;
            }

            list.Clear();
            list.Add(new CssMedium
            {
                IsInverse = true,
                Type      = Keywords.All
            });
        }
Пример #16
0
        /// <summary>
        /// 4.4.20. URL-end state
        /// </summary>
        CssToken UrlEnd(Char current, CssTokenType type)
        {
            while (true)
            {
                if (current == Specification.RoundBracketClose)
                    return CssStringToken.Url(type, FlushBuffer());
                else if (!current.IsSpaceCharacter())
                {
                    RaiseErrorOccurred(ErrorCode.InvalidCharacter);
                    return UrlBad(current, type);
                }

                current = Next;
            }
        }
Пример #17
0
 public CssToken(CssTokenType type, String data, TextPosition position)
 {
     _type = type;
     _data = data;
     _position = position;
 }
		private void acceptElement(CssTokenType t)
		{
			CssToken ct = tokenizer.Current;
			
			while (tokenizer.Current.GetTokenType () == CssTokenType.COMMENT) {
				tokenizer.MoveNext ();
				Console.WriteLine("ignored comment");
			}
			
			if (tokenizer.Current.GetTokenType () != t) {
				Console.WriteLine("Parser: Rejected Terminal: {0} {1} - Expected {2}", ct.GetValue (), ct.GetTokenType ().ToString (), t.ToString ());
				throw new Exception("I made a boo!");
			} else {
				currentNode.AddChild(new CssNode(tokenizer.Current));
				Console.WriteLine("Parser: Accepted Terminal: {0} {1}", tokenizer.Current.GetValue (), tokenizer.Current.GetTokenType ().ToString ());
			}
			tokenizer.MoveNext ();
		}
Пример #19
0
        /// <summary>
        /// Before any medium has been found for the @media or @import rule.
        /// </summary>
        void FillMediaList(MediaList list, CssTokenType end, ref CssToken token)
        {
            if (token.Type == end)
                return;

            while (token.Type != CssTokenType.Eof)
            {
                var medium = CreateMedium(ref token);

                if (medium != null)
                    list.Add(medium);

                if (token.Type != CssTokenType.Comma)
                    break;

                token = _tokenizer.Get();
            }

            if (token.Type == end && list.Length > 0)
                return;

            list.Clear();
            list.Add(new CssMedium
            {
                IsInverse = true,
                Type = Keywords.All
            });
        }
Пример #20
0
 public StartsWithValueConverter(CssTokenType type, String data, IValueConverter converter)
 {
     _type      = type;
     _data      = data;
     _converter = converter;
 }
Пример #21
0
        /// <summary>
        /// 4.4.21. URL-unquoted state
        /// </summary>
        CssToken UrlUQ(Char current, CssTokenType type)
        {
            while (true)
            {
                if (current.IsSpaceCharacter())
                {
                    return UrlEnd(_src.Next, type);
                }
                else if (current == Specification.RBC || current == Specification.EOF)
                {
                    return CssStringToken.Url(type, FlushBuffer());
                }
                else if (current == Specification.DQ || current == Specification.SQ || current == Specification.RBO || current.IsNonPrintable())
                {
                    RaiseErrorOccurred(ErrorCode.InvalidCharacter);
                    return UrlBad(_src.Next, type);
                }
                else if (current == Specification.RSOLIDUS)
                {
                    if (IsValidEscape(current))
                    {
                        current = _src.Next;
                        _stringBuffer.Append(ConsumeEscape(current));
                    }
                    else
                    {
                        RaiseErrorOccurred(ErrorCode.InvalidCharacter);
                        return UrlBad(_src.Next, type);
                    }
                }
                else
                    _stringBuffer.Append(current);

                current = _src.Next;
            }
        }
Пример #22
0
 public CssUnitToken(CssTokenType type, String value, String dimension, TextPosition position)
     : base(type, value, position)
 {
     _unit = dimension;
 }
Пример #23
0
        /// <summary>
        /// Checks if the provided token is either of the first or the second
        /// type of token.
        /// </summary>
        /// <param name="token">The token to examine.</param>
        /// <param name="a">The first type to match.</param>
        /// <param name="b">The alternative match for the token.</param>
        /// <returns>Result of the examination.</returns>
        public static Boolean Is(this CssToken token, CssTokenType a, CssTokenType b)
        {
            var type = token.Type;

            return(type == a || type == b);
        }
Пример #24
0
        /// <summary>
        /// Checks if the provided token is neither of the first, nor the
        /// second nor the third type of token.
        /// </summary>
        /// <param name="token">The token to examine.</param>
        /// <param name="a">The first type to unmatch.</param>
        /// <param name="b">The alternative unmatch for the token.</param>
        /// <param name="c">The final unmatch for the token.</param>
        /// <returns>Result of the examination.</returns>
        public static Boolean IsNot(this CssToken token, CssTokenType a, CssTokenType b, CssTokenType c)
        {
            var type = token.Type;

            return(type != a && type != b && type != c);
        }
Пример #25
0
        /// <summary>
        /// 4.4.20. URL-end state
        /// </summary>
        CssToken UrlEnd(CssTokenType type)
        {
            while (true)
            {
                var current = GetNext();

                if (current == Symbols.RoundBracketClose)
                {
                    return NewUrl(type, FlushBuffer());
                }
                else if (!current.IsSpaceCharacter())
                {
                    RaiseErrorOccurred(CssParseError.InvalidCharacter);
                    Back();
                    return UrlBad(type);
                }
            }
        }
Пример #26
0
 /// <summary>
 /// Checks if the provided token is neither of the first, nor the
 /// second nor the third type of token.
 /// </summary>
 /// <param name="token">The token to examine.</param>
 /// <param name="a">The first type to unmatch.</param>
 /// <param name="b">The alternative unmatch for the token.</param>
 /// <param name="c">The final unmatch for the token.</param>
 /// <returns>Result of the examination.</returns>
 public static Boolean IsNot(this CssToken token, CssTokenType a, CssTokenType b, CssTokenType c)
 {
     var type = token.Type;
     return type != a && type != b && type != c;
 }
Пример #27
0
 /// <summary>
 /// Checks if the provided token is either of the first or the second 
 /// type of token.
 /// </summary>
 /// <param name="token">The token to examine.</param>
 /// <param name="a">The first type to match.</param>
 /// <param name="b">The alternative match for the token.</param>
 /// <returns>Result of the examination.</returns>
 public static Boolean Is(this CssToken token, CssTokenType a, CssTokenType b)
 {
     var type = token.Type;
     return type == a || type == b;
 }
Пример #28
0
        /// <summary>
        /// 4.4.19. URL-single-quoted state
        /// </summary>
        CssToken UrlSQ(CssTokenType type)
        {
            while (true)
            {
                var current = GetNext();

                if (current.IsLineBreak())
                {
                    RaiseErrorOccurred(CssParseError.LineBreakUnexpected);
                    return UrlBad(type);
                }
                else if (Symbols.EndOfFile == current)
                {
                    return NewUrl(type, FlushBuffer());
                }
                else if (current == Symbols.SingleQuote)
                {
                    return UrlEnd(type);
                }
                else if (current != Symbols.ReverseSolidus)
                {
                    _stringBuffer.Append(current);
                }
                else
                {
                    current = GetNext();

                    if (current == Symbols.EndOfFile)
                    {
                        Back(2);
                        RaiseErrorOccurred(CssParseError.EOF);
                        return NewUrl(type, FlushBuffer(), bad: true);
                    }
                    else if (current.IsLineBreak())
                        _stringBuffer.AppendLine();
                    else
                        _stringBuffer.Append(ConsumeEscape(current));
                }
            }
        }
Пример #29
0
        /// <summary>
        /// 4.4.17. URL state
        /// </summary>
        CssToken UrlStart(CssTokenType type)
        {
            var current = SkipSpaces();

            switch (current)
            {
                case Symbols.EndOfFile:
                    RaiseErrorOccurred(CssParseError.EOF);
                    return NewUrl(type, String.Empty, bad: true);

                case Symbols.DoubleQuote:
                    return UrlDQ(type);

                case Symbols.SingleQuote:
                    return UrlSQ(type);

                case Symbols.RoundBracketClose:
                    return NewUrl(type, String.Empty, bad: false);

                default:
                    return UrlUQ(current, type);
            }
        }
Пример #30
0
        /// <summary>
        /// 4.4.17. URL state
        /// </summary>
        CssToken UrlStart(Char current, CssTokenType type)
        {
            while (current.IsSpaceCharacter())
                current = Next;

            switch (current)
            {
                case Specification.EndOfFile:
                    RaiseErrorOccurred(ErrorCode.EOF);
                    return CssStringToken.Url(type, String.Empty, true);

                case Specification.DoubleQuote:
                    return UrlDQ(Next, type);

                case Specification.SingleQuote:
                    return UrlSQ(Next, type);

                case ')':
                    return CssStringToken.Url(type, String.Empty, false);

                default:
                    return UrlUQ(current, type);
            }
        }
Пример #31
0
 /// <summary>
 /// Creates a new CSS keyword token.
 /// </summary>
 /// <param name="type">The exact type.</param>
 /// <param name="data">The data to use.</param>
 /// <param name="position">The token's position.</param>
 public CssKeywordToken(CssTokenType type, String data, TextPosition position)
     : base(type, data, position)
 {
 }
Пример #32
0
        private void FillMediaList(MediaList list, CssTokenType end, ref CssToken token)
        {
            _nodes.Push(list);

            if (token.Type != end)
            {
                while (token.Type != CssTokenType.EndOfFile)
                {
                    var medium = CreateMedium(ref token);

                    if (medium != null)
                    {
                        list.AppendChild(medium);
                    }

                    if (token.Type != CssTokenType.Comma)
                    {
                        break;
                    }

                    token = NextToken();
                    CollectTrivia(ref token);
                }

                if (token.Type != end || list.Length == 0)
                {
                    list.Clear();
                    list.AppendChild(new CssMedium
                    {
                        IsInverse = true,
                        Type = Keywords.All
                    });
                }
            }

            _nodes.Pop();
        }
Пример #33
0
        protected virtual bool HandleToken()
        {
            CssTokenType tokenType  = CssTokenType.Unknown;
            int          tokenStart = CS.Position;

            switch (CS.CurrentChar)
            {
            case '*':
                if (CS.Peek(1) == '=')
                {
                    tokenType = CssTokenType.ContainsString;
                    CS.Advance(1);
                }
                else
                {
                    tokenType = CssTokenType.Asterisk;
                }
                break;

            case '&':
                tokenType = CssTokenType.Ampersand;
                break;

            case '.':
                tokenType = CssTokenType.Dot;
                break;

            case '!':
                tokenType = CssTokenType.Bang;
                break;

            case ',':
                tokenType = CssTokenType.Comma;
                break;

            case '^':
                if (CS.Peek(1) == '=')
                {
                    tokenType = CssTokenType.BeginsWith;
                    CS.Advance(1);
                }
                else
                {
                    tokenType = CssTokenType.Caret;
                }
                break;

            case ':':
                if (CS.Peek(1) == ':')
                {
                    tokenType = CssTokenType.DoubleColon;
                    CS.Advance(1);
                }
                else
                {
                    tokenType = CssTokenType.Colon;
                }
                break;

            case '$':
                if (CS.Peek(1) == '=')
                {
                    tokenType = CssTokenType.EndsWith;
                    CS.Advance(1);
                }
                else
                {
                    tokenType = CssTokenType.Dollar;
                }
                break;

            case '=':
                tokenType = CssTokenType.Equals;
                break;

            case '>':
                tokenType = CssTokenType.Greater;
                break;

            case '|':
                if (CS.Peek(1) == '=')
                {
                    tokenType = CssTokenType.ListBeginsWith;
                    CS.Advance(1);
                }
                else if (CS.Peek(1) == '|')
                {
                    tokenType = CssTokenType.DoublePipe;
                    CS.Advance(1);
                }
                else
                {
                    tokenType = CssTokenType.Or;
                }
                break;

            case '%':
                tokenType = CssTokenType.Percent;
                break;

            case ';':
                tokenType = CssTokenType.Semicolon;
                break;

            case '/':
                if (HandleComment())
                {
                    return(true);
                }
                else
                {
                    tokenType = CssTokenType.Slash;
                }
                break;

            case '\\':
                if (HandleSlashNineHack())
                {
                    return(true);
                }
                break;

            case '<':
                if (CS.TextProvider.CompareTo(CS.Position, "<!--", ignoreCase: false))
                {
                    CS.Advance(4);
                    AddToken(CssTokenType.OpenHtmlComment, tokenStart, CS.Position - tokenStart);
                    return(true);
                }
                break;

            case '~':
                if (CS.Peek(1) == '=')
                {
                    tokenType = CssTokenType.OneOf;
                    CS.Advance(1);
                }
                else
                {
                    tokenType = CssTokenType.Tilde;
                }
                break;

            case '(':
                tokenType = CssTokenType.OpenFunctionBrace;
                break;

            case ')':
                tokenType = CssTokenType.CloseFunctionBrace;
                break;

            case '[':
                tokenType = CssTokenType.OpenSquareBracket;
                break;

            case ']':
                tokenType = CssTokenType.CloseSquareBracket;
                break;

            case '{':
                tokenType = CssTokenType.OpenCurlyBrace;
                break;

            case '}':
                tokenType = CssTokenType.CloseCurlyBrace;
                break;

            case '@':
                tokenType = CssTokenType.At;
                break;

            case '\'':
            case '\"':
                if (HandleString() != CssTokenType.Unknown)
                {
                    return(true);
                }
                break;

            case '#':
                if (HandleHash())
                {
                    return(true);
                }
                else
                {
                    tokenType = CssTokenType.Hash;
                }
                break;

            case '+':
                tokenType = CssTokenType.Plus;
                break;

            case '-':
                if (HandleIdentifier())
                {
                    return(true);
                }
                else if (CS.TextProvider.CompareTo(CS.Position, "-->", ignoreCase: false))
                {
                    CS.Advance(3);
                    AddToken(CssTokenType.CloseHtmlComment, tokenStart, CS.Position - tokenStart);
                    return(true);
                }
                else
                {
                    tokenType = CssTokenType.Minus;
                }
                break;

            case 'u':
            case 'U':
                if (HandleUnicodeRange())
                {
                    return(true);
                }
                break;
            }

            if (tokenType == CssTokenType.Unknown &&
                HandleIdentifier())
            {
                return(true);
            }

            if (!HandleUnknown())
            {
                // Some kind of junk in the CSS, just deal with it by making an unknown token
                CS.Advance(1);
                AddToken(tokenType, tokenStart, CS.Position - tokenStart);
            }

            return(true);
        }
Пример #34
0
        private CssValue CreateValue(CssTokenType closing, ref CssToken token, out Boolean important)
        {
            var value = Pool.NewValueBuilder();
            _tokenizer.IsInValue = true;
            token = NextToken();
            var start = token.Position;

            while (token.IsNot(CssTokenType.EndOfFile, CssTokenType.Semicolon, closing))
            {
                value.Apply(token);
                token = NextToken();
            }

            important = value.IsImportant;
            _tokenizer.IsInValue = false;
            var valueIsValid = value.IsValid;
            var result = value.ToPool();
            var node = result as CssNode;

            if (node != null)
            {
                var end = token.Position.Shift(-1);
                node.SourceCode = CreateView(start, end);
            }

            if (!valueIsValid && !_parser.Options.IsToleratingInvalidValues)
            {
                RaiseErrorOccurred(CssParseError.InvalidValue, start);
                result = null;
            }

            return result;
        }
Пример #35
0
 CssToken NewUrl(CssTokenType type, String data, Boolean bad = false)
 {
     return new CssStringToken(type, data, bad, _position);
 }
Пример #36
0
 /// <summary>
 /// Creates a new comment.
 /// </summary>
 CssCommentToken(CssTokenType type, String data)
     : base(type, data)
 {
 }
Пример #37
0
        /// <summary>
        /// Called before any token in the value regime had been seen.
        /// </summary>
        CssValue CreateValue(CssTokenType closing, ref CssToken token, out Boolean important)
        {
            var value = Pool.NewValueBuilder();
            _tokenizer.State = CssParseMode.Value;
            token = _tokenizer.Get();

            while (token.Type != CssTokenType.Eof)
            {
                if (token.Is(CssTokenType.Semicolon, closing))
                    break;

                value.Apply(token);
                token = _tokenizer.Get();
            }

            important = value.IsImportant;
            _tokenizer.State = CssParseMode.Data;

            if (value.IsValid || _parser.Options.IsToleratingInvalidValues)
                return value.ToPool();

            value.ToPool();
            return null;
        }
Пример #38
0
 public StartsWithValueConverter(CssTokenType type, String data, IValueConverter converter)
 {
     _type = type;
     _data = data;
     _converter = converter;
 }
 public CssSelectorToken(CssTokenType type, String data)
 {
     _type = type;
     _data = data;
 }
Пример #40
0
 /// <summary>
 /// Creates a new CSS string token.
 /// </summary>
 /// <param name="type">The exact type.</param>
 CssStringToken(CssTokenType type)
 {
     _type = type;
 }
Пример #41
0
 /// <summary>
 /// Creates a new CSS unit token.
 /// </summary>
 /// <param name="type">The exact type.</param>
 CssUnitToken(CssTokenType type)
 {
     _type = type;
 }
Пример #42
0
 public CssToken(CssTokenType type, String data, TextPosition position)
 {
     _type     = type;
     _data     = data;
     _position = position;
 }
Пример #43
0
        /// <summary>
        /// 4.4.22. Bad URL state
        /// </summary>
        CssToken UrlBad(Char current, CssTokenType type)
        {
            while (true)
            {
                if (current == Specification.EndOfFile)
                {
                    RaiseErrorOccurred(ErrorCode.EOF);
                    return CssStringToken.Url(type, FlushBuffer(), true);
                }
                else if (current == Specification.RoundBracketClose)
                {
                    return CssStringToken.Url(type, FlushBuffer(), true);
                }
                else if (IsValidEscape(current))
                {
                    current = Next;
                    _stringBuffer.Append(ConsumeEscape(current));
                }

                current = Next;
            }
        }
Пример #44
0
        static CssToken ConsumeNodeName(string src, ref int index, bool validateFirstChar, CssTokenType type)
        {
            int start = index;

            if (!validateFirstChar)
            {
                ++index;
            }

            while (index < src.Length && ">~+,:.#()[] ".IndexOf(src[index]) == -1)
            {
                ++index;
            }
            if (index == start)
            {
                throw new Exception("how did we end up with a 0-length tag name starting at " + index + " for:" + src);
            }
            return(new CssToken(src.Substring(start, index - start), type));
        }
Пример #45
0
        /// <summary>
        /// 4.4.19. URL-single-quoted state
        /// </summary>
        CssToken UrlSQ(Char current, CssTokenType type)
        {
            while (true)
            {
                if (current.IsLineBreak())
                {
                    RaiseErrorOccurred(ErrorCode.LineBreakUnexpected);
                    return UrlBad(Next, type);
                }
                else if (Specification.EndOfFile == current)
                {
                    return CssStringToken.Url(type, FlushBuffer());
                }
                else if (current == Specification.SingleQuote)
                {
                    return UrlEnd(Next, type);
                }
                else if (current == Specification.ReverseSolidus)
                {
                    current = Next;

                    if (current == Specification.EndOfFile)
                    {
                        Back(2);
                        RaiseErrorOccurred(ErrorCode.EOF);
                        return CssStringToken.Url(type, FlushBuffer(), true);
                    }
                    else if (current.IsLineBreak())
                        _stringBuffer.AppendLine();
                    else
                        _stringBuffer.Append(ConsumeEscape(current));
                }
                else
                    _stringBuffer.Append(current);

                current = Next;
            }
        }
Пример #46
0
        /// <summary>
        /// 4.4.21. URL-unquoted state
        /// </summary>
        CssToken UrlUQ(Char current, CssTokenType type)
        {
            while (true)
            {
                if (current.IsSpaceCharacter())
                {
                    return UrlEnd(type);
                }
                else if (current == Symbols.RoundBracketClose || current == Symbols.EndOfFile)
                {
                    return NewUrl(type, FlushBuffer());
                }
                else if (current == Symbols.DoubleQuote || current == Symbols.SingleQuote || current == Symbols.RoundBracketOpen || current.IsNonPrintable())
                {
                    RaiseErrorOccurred(CssParseError.InvalidCharacter);
                    return UrlBad(type);
                }
                else if (current != Symbols.ReverseSolidus)
                {
                    _stringBuffer.Append(current);
                }
                else if (IsValidEscape(current))
                {
                    current = GetNext();
                    _stringBuffer.Append(ConsumeEscape(current));
                }
                else
                {
                    RaiseErrorOccurred(CssParseError.InvalidCharacter);
                    return UrlBad(type);
                }

                current = GetNext();
            }
        }
Пример #47
0
        /// <summary>
        /// 4.4.21. URL-unquoted state
        /// </summary>
        CssToken UrlUQ(Char current, CssTokenType type)
        {
            while (true)
            {
                if (current.IsSpaceCharacter())
                {
                    return UrlEnd(Next, type);
                }
                else if (current == Specification.RoundBracketClose || current == Specification.EndOfFile)
                {
                    return CssStringToken.Url(type, FlushBuffer());
                }
                else if (current == Specification.DoubleQuote || current == Specification.SingleQuote || current == Specification.RoundBracketOpen || current.IsNonPrintable())
                {
                    RaiseErrorOccurred(ErrorCode.InvalidCharacter);
                    return UrlBad(Next, type);
                }
                else if (current == Specification.ReverseSolidus)
                {
                    if (IsValidEscape(current))
                    {
                        current = Next;
                        _stringBuffer.Append(ConsumeEscape(current));
                    }
                    else
                    {
                        RaiseErrorOccurred(ErrorCode.InvalidCharacter);
                        return UrlBad(Next, type);
                    }
                }
                else
                    _stringBuffer.Append(current);

                current = Next;
            }
        }
Пример #48
0
 public CssToken(CssTokenType type, Char data, TextPosition position)
     : this(type, data.ToString(), position)
 {
 }
Пример #49
0
 /// <summary>
 /// Creates a new CSS string token (URL string).
 /// </summary>
 /// <param name="token">The token type (url, urlprefix, domain).</param>
 /// <param name="data">The URL string data.</param>
 /// <param name="bad">If the URL was bad (optional).</param>
 /// <returns>The created URL string token.</returns>
 public static CssStringToken Url(CssTokenType token, String data, Boolean bad = false)
 {
     return new CssStringToken(token) { _data = data, _bad = bad };
 }
Пример #50
0
        /// <summary>
        /// Appends media labels from the given source to the medialist.
        /// </summary>
        /// <param name="source">The token iterator.</param>
        /// <param name="media">The medialist to append to.</param>
        /// <param name="endToken">The optional token type to finish appending to the list.</param>
        void AppendMediaList(IEnumerator<CssToken> source, MediaList media, CssTokenType endToken = CssTokenType.Semicolon)
        {
            do
            {
                if (source.Current.Type == CssTokenType.Whitespace)
                    continue;
                else if (source.Current.Type == endToken)
                    break;

                do
                {
                    if (source.Current.Type == CssTokenType.Comma || source.Current.Type == endToken)
                        break;
                    else if (source.Current.Type == CssTokenType.Whitespace)
                        buffer.Append(' ');
                    else
                        buffer.Append(source.Current.ToValue());
                }
                while (source.MoveNext());

                media.AppendMedium(buffer.ToString());
                buffer.Clear();

                if (source.Current.Type == endToken)
                    break;
            }
            while (source.MoveNext());
        }
Пример #51
0
        protected CssTokenType SkipString()
        {
            // This can detect single and double quoted strings, spanning a single or multiple lines.
            // Also, unterminated strings are detected. The return value tells you the type:
            //
            // CssTokenType.Unknown (not a string at all)
            // CssTokenType.MultilineString
            // CssTokenType.String
            // CssTokenType.InvalidString (unterminated)

            CssTokenType tokenType = CssTokenType.Unknown;

            if (TextHelper.IsQuote(CS.CurrentChar))
            {
                // Guilty until proven valid
                tokenType = CssTokenType.InvalidString;

                char quote     = CS.CurrentChar;
                bool multiLine = false;

                CS.Advance(1);

                while (!CS.IsAtEnd)
                {
                    if (AtScopeBlocker())
                    {
                        break;
                    }
                    else if (CS.CurrentChar == quote)
                    {
                        // Found matching end quote
                        tokenType = multiLine ? CssTokenType.MultilineString : CssTokenType.String;

                        CS.Advance(1);
                        break;
                    }
                    else if (TextHelper.IsNewLine(CS.CurrentChar))
                    {
                        break;
                    }
                    else if (AtEscape())
                    {
                        SkipEscape();
                    }
                    else if (CS.CurrentChar == '\\')
                    {
                        // must be an escaped line break
                        CS.Advance(1);

                        Debug.Assert(TextHelper.IsNewLine(CS.CurrentChar));
                        SkipNewLine();

                        multiLine = true;
                    }
                    else
                    {
                        CS.Advance(1);
                    }
                }

                if (tokenType == CssTokenType.InvalidString)
                {
                    SkipWhitespaceReverse();
                }
            }

            return(tokenType);
        }
Пример #52
0
 /// <summary>
 /// Creates a new CSS keyword token.
 /// </summary>
 /// <param name="type">The exact type.</param>
 /// <param name="data">The data to use.</param>
 CssKeywordToken(CssTokenType type, String data)
     : base(type, data)
 {
 }
Пример #53
0
        private bool HandleComment()
        {
            const CssTokenType startTokenType = CssTokenType.OpenCComment;
            const CssTokenType endTokenType   = CssTokenType.CloseCComment;
            const string       commentStart   = "/*";
            const string       commentEnd     = "*/";

            if (AtScopeBlocker())
            {
                AddToken(CssTokenType.ScopeBlocker, CS.Position, ScopeBlockerText.Length);
                CS.Advance(ScopeBlockerText.Length);

                return(true);
            }

            // Comment: /* foo */
            // Makes three tokens for a comment (start, text, and end)

            if (!CS.TextProvider.CompareTo(CS.Position, commentStart, ignoreCase: false))
            {
                return(false);
            }

            // Skip the start of the comment

            AddToken(startTokenType, CS.Position, commentStart.Length);
            CS.Advance(commentStart.Length);

            // Skip the inner text of the comment

            bool endFound = false;

            if (!CS.IsAtEnd)
            {
                SkipWhitespace();

                int start = CS.Position;

                for (; !CS.IsAtEnd; CS.Advance(1))
                {
                    if (CS.TextProvider.CompareTo(CS.Position, commentEnd, ignoreCase: false))
                    {
                        endFound = true;
                        break;
                    }

                    if (AtScopeBlocker())
                    {
                        // Catch: /* Foo /* END EXTERNAL SOURCE */
                        break;
                    }
                }

                if (CS.Position >= start)
                {
                    // Create a token for the comment text, don't include trailing whitespace
                    SkipWhitespaceReverse();

                    if (CS.Position > start)
                    {
                        AddToken(CssTokenType.CommentText, start, CS.Position - start);
                    }

                    SkipWhitespace();
                }
            }

            // Skip the end of the comment

            if (endFound)
            {
                AddToken(endTokenType, CS.Position, commentEnd.Length);
                CS.Advance(commentEnd.Length);
            }

            return(true);
        }
Пример #54
0
 /// <summary>
 /// Creates a new special character token.
 /// </summary>
 /// <param name="c">The character to contain.</param>
 /// <param name="type">The actual token type.</param>
 CssSpecialCharacter(Char c, CssTokenType type)
     : base(c)
 {
     _type = type;
 }
Пример #55
0
 public CssToken(CssTokenType type, Char data, TextPosition position)
     : this(type, data.ToString(), position)
 {
 }
Пример #56
0
        /// <summary>
        /// 4.4.22. Bad URL state
        /// </summary>
        CssToken UrlBad(CssTokenType type)
        {
            var current = Current;
            var curly = 0;
            var round = 1;

            while (current != Symbols.EndOfFile)
            {
                if (current == Symbols.Semicolon)
                {
                    Back();
                    return NewUrl(type, FlushBuffer(), true);
                }
                else if (current == Symbols.CurlyBracketClose && --curly == -1)
                {
                    Back();
                    return NewUrl(type, FlushBuffer(), true);
                }
                else if (current == Symbols.RoundBracketClose && --round == 0)
                {
                    return NewUrl(type, FlushBuffer(), true);
                }
                else if (IsValidEscape(current))
                {
                    current = GetNext();
                    _stringBuffer.Append(ConsumeEscape(current));
                }
                else
                {
                    if (current == Symbols.RoundBracketOpen)
                        ++round;
                    else if (curly == Symbols.CurlyBracketOpen)
                        ++curly;

                    _stringBuffer.Append(current);
                }

                current = GetNext();
            }

            RaiseErrorOccurred(CssParseError.EOF);
            return NewUrl(type, FlushBuffer(), bad: true);
        }
Пример #57
0
 public CssKeywordToken(CssTokenType type, String data, TextPosition position)
     : base(type, data, position)
 {
 }
Пример #58
0
 /// <summary>
 /// Creates a new CSS unit token.
 /// </summary>
 /// <param name="type">The exact type.</param>
 /// <param name="value">The value.</param>
 /// <param name="dimension">The unit (dimension).</param>
 /// <param name="position">The token's position.</param>
 public CssUnitToken(CssTokenType type, String value, String dimension, TextPosition position)
     : base(type, value, position)
 {
     _unit = dimension;
 }
Пример #59
0
        static void ConsumeOpenCloseGroup(string src, ref int index, List <CssToken> tokens, char closeChar, CssTokenType groupType)
        {
            char openChar = src[index++];

            int closeIndex = src.IndexOf(closeChar, index);

            if (closeIndex < index)
            {
                throw new FormatException("'" + openChar + "' at " + (index - 1) + " has no matching '" + closeChar + "'");
            }

            // this works since () [] {} are non-nestable (I think)
            // return everything inside () as a single token. Let consumers parse them out
            tokens.Add(new CssToken(openChar.ToString(), groupType));
            tokens.Add(new CssToken(src.Substring(index, closeIndex - index).Trim(), CssTokenType.Parameter));
            tokens.Add(new CssToken(closeChar.ToString(), groupType));
            index = closeIndex + 1;
        }
 /// <summary>
 /// Creates a new CSS string token.
 /// </summary>
 /// <param name="type">The exact type.</param>
 CssStringToken(CssTokenType type)
 {
     _type = type;
 }