/// <summary> /// 4.4.19. URL-single-quoted state /// </summary> CssToken UrlSQ(CssTokenType type) { while (true) { var current = GetNext(); if (current.IsLineBreak()) { RaiseErrorOccurred(ErrorCode.LineBreakUnexpected); return(UrlBad(type)); } else if (Symbols.EndOfFile == current) { return(CssStringToken.Url(type, FlushBuffer())); } else if (current == Symbols.SingleQuote) { return(UrlEnd(type)); } else if (current == Symbols.ReverseSolidus) { current = GetNext(); if (current == Symbols.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); } } }
/// <summary> /// 4.4.2. Double quoted string state /// </summary> CssToken StringDQ() { while (true) { var current = GetNext(); switch (current) { case Symbols.DoubleQuote: case Symbols.EndOfFile: return(CssStringToken.Plain(FlushBuffer())); case Symbols.FormFeed: case Symbols.LineFeed: RaiseErrorOccurred(ErrorCode.LineBreakUnexpected); Back(); return(CssStringToken.Plain(FlushBuffer(), true)); case Symbols.ReverseSolidus: current = GetNext(); if (current.IsLineBreak()) { _stringBuffer.AppendLine(); } else if (current != Symbols.EndOfFile) { _stringBuffer.Append(ConsumeEscape(current)); } else { RaiseErrorOccurred(ErrorCode.EOF); Back(); return(CssStringToken.Plain(FlushBuffer(), true)); } break; default: _stringBuffer.Append(current); break; } } }
/// <summary> /// 4.4.18. URL-double-quoted state /// </summary> CssToken UrlDQ(Char current, CssTokenType type) { while (true) { if (current.IsLineBreak()) { RaiseErrorOccurred(ErrorCode.LineBreakUnexpected); return(UrlBad(_src.Next, type)); } else if (Specification.EndOfFile == current) { return(CssStringToken.Url(type, FlushBuffer())); } else if (current == Specification.DoubleQuote) { return(UrlEnd(_src.Next, type)); } else if (current == Specification.ReverseSolidus) { current = _src.Next; if (current == Specification.EndOfFile) { _src.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 = _src.Next; } }
/// <summary> /// 4.4.3. Single quoted string state /// </summary> CssToken StringSQ(Char current) { while (true) { switch (current) { case Specification.SingleQuote: case Specification.EndOfFile: return(CssStringToken.Plain(FlushBuffer())); case Specification.FormFeed: case Specification.LineFeed: RaiseErrorOccurred(ErrorCode.LineBreakUnexpected); _src.Back(); return(CssStringToken.Plain(FlushBuffer(), true)); case Specification.ReverseSolidus: current = _src.Next; if (current.IsLineBreak()) { _stringBuffer.AppendLine(); } else if (current != Specification.EndOfFile) { _stringBuffer.Append(ConsumeEscape(current)); } else { RaiseErrorOccurred(ErrorCode.EOF); _src.Back(); return(CssStringToken.Plain(FlushBuffer(), true)); } break; default: _stringBuffer.Append(current); break; } current = _src.Next; } }
/// <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)); } } }
/// <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; } }
/// <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(CssStringToken.Url(type, FlushBuffer())); } else if (current == Symbols.DoubleQuote || current == Symbols.SingleQuote || current == Symbols.RoundBracketOpen || current.IsNonPrintable()) { RaiseErrorOccurred(ErrorCode.InvalidCharacter); return(UrlBad(type)); } else if (current == Symbols.ReverseSolidus) { if (IsValidEscape(current)) { current = GetNext(); _stringBuffer.Append(ConsumeEscape(current)); } else { RaiseErrorOccurred(ErrorCode.InvalidCharacter); return(UrlBad(type)); } } else { _stringBuffer.Append(current); } current = GetNext(); } }
/// <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)); } }