Пример #1
0
        /// <summary>
        /// See 8.2.4.35 Attribute name state
        /// </summary>
        /// <param name="tag">The current tag token.</param>
        HtmlToken AttributeName(HtmlTagToken tag)
        {
            while (true)
            {
                var c = GetNext();

                if (c == Symbols.Equality)
                {
                    tag.AddAttribute(_stringBuffer.ToString());
                    _stringBuffer.Clear();
                    return AttributeBeforeValue(tag);
                }
                else if (c == Symbols.GreaterThan)
                {
                    tag.AddAttribute(_stringBuffer.ToString());
                    _stringBuffer.Clear();
                    return EmitTag(tag);
                }
                else if (c.IsSpaceCharacter())
                {
                    tag.AddAttribute(_stringBuffer.ToString());
                    _stringBuffer.Clear();
                    return AttributeAfterName(tag);
                }
                else if (c == Symbols.Solidus)
                {
                    tag.AddAttribute(_stringBuffer.ToString());
                    _stringBuffer.Clear();
                    return TagSelfClosing(tag);
                }
                else if (c.IsUppercaseAscii())
                {
                    _stringBuffer.Append(Char.ToLower(c));
                }
                else if (c == Symbols.DoubleQuote || c == Symbols.SingleQuote || c == Symbols.LessThan)
                {
                    RaiseErrorOccurred(HtmlParseError.AttributeNameInvalid);
                    _stringBuffer.Append(c);
                }
                else if(c == Symbols.Null)
                {
                    RaiseErrorOccurred(HtmlParseError.Null);
                    _stringBuffer.Append(Symbols.Replacement);
                }
                else if (c != Symbols.EndOfFile)
                {
                    _stringBuffer.Append(c);
                }
                else
                {
                    return NewEof();
                }
            }
        }
Пример #2
0
        private HtmlToken ParseAttributes(HtmlTagToken tag)
        {
            var state = AttributeState.BeforeName;
            var quote = Symbols.DoubleQuote;
            var c = Symbols.Null;

            while (true)
            {
                switch (state)
                {
                    // See 8.2.4.34 Before attribute name state
                    case AttributeState.BeforeName:
                    {
                        c = SkipSpaces();

                        if (c == Symbols.Solidus)
                        {
                            return TagSelfClosing(tag);
                        }
                        else if (c == Symbols.GreaterThan)
                        {
                            return EmitTag(tag);
                        }
                        else if (c.IsUppercaseAscii())
                        {
                            StringBuffer.Append(Char.ToLowerInvariant(c));
                            state = AttributeState.Name;
                        }
                        else if (c == Symbols.Null)
                        {
                            AppendReplacement();
                            state = AttributeState.Name;
                        }
                        else if (c == Symbols.SingleQuote || c == Symbols.DoubleQuote || c == Symbols.Equality || c == Symbols.LessThan)
                        {
                            RaiseErrorOccurred(HtmlParseError.AttributeNameInvalid);
                            StringBuffer.Append(c);
                            state = AttributeState.Name;
                        }
                        else if (c != Symbols.EndOfFile)
                        {
                            StringBuffer.Append(c);
                            state = AttributeState.Name;
                        }
                        else
                        {
                            return NewEof();
                        }

                        break;
                    }

                    // See 8.2.4.35 Attribute name state
                    case AttributeState.Name:
                    {
                        c = GetNext();

                        if (c == Symbols.Equality)
                        {
                            tag.AddAttribute(FlushBuffer());
                            state = AttributeState.BeforeValue;
                        }
                        else if (c == Symbols.GreaterThan)
                        {
                            tag.AddAttribute(FlushBuffer());
                            return EmitTag(tag);
                        }
                        else if (c.IsSpaceCharacter())
                        {
                            tag.AddAttribute(FlushBuffer());
                            state = AttributeState.AfterName;
                        }
                        else if (c == Symbols.Solidus)
                        {
                            tag.AddAttribute(FlushBuffer());
                            return TagSelfClosing(tag);
                        }
                        else if (c.IsUppercaseAscii())
                        {
                            StringBuffer.Append(Char.ToLowerInvariant(c));
                        }
                        else if (c == Symbols.DoubleQuote || c == Symbols.SingleQuote || c == Symbols.LessThan)
                        {
                            RaiseErrorOccurred(HtmlParseError.AttributeNameInvalid);
                            StringBuffer.Append(c);
                        }
                        else if (c == Symbols.Null)
                        {
                            AppendReplacement();
                        }
                        else if (c != Symbols.EndOfFile)
                        {
                            StringBuffer.Append(c);
                        }
                        else
                        {
                            return NewEof();
                        }

                        break;
                    }

                    // See 8.2.4.36 After attribute name state
                    case AttributeState.AfterName:
                    {
                        c = SkipSpaces();

                        if (c == Symbols.GreaterThan)
                        {
                            return EmitTag(tag);
                        }
                        else if (c == Symbols.Equality)
                        {
                            state = AttributeState.BeforeValue;
                        }
                        else if (c == Symbols.Solidus)
                        {
                            return TagSelfClosing(tag);
                        }
                        else if (c.IsUppercaseAscii())
                        {
                            StringBuffer.Append(Char.ToLowerInvariant(c));
                            state = AttributeState.Name;
                        }
                        else if (c == Symbols.DoubleQuote || c == Symbols.SingleQuote || c == Symbols.LessThan)
                        {
                            RaiseErrorOccurred(HtmlParseError.AttributeNameInvalid);
                            StringBuffer.Append(c);
                            state = AttributeState.Name;
                        }
                        else if (c == Symbols.Null)
                        {
                            AppendReplacement();
                            state = AttributeState.Name;
                        }
                        else if (c != Symbols.EndOfFile)
                        {
                            StringBuffer.Append(c);
                            state = AttributeState.Name;
                        }
                        else
                        {
                            return NewEof();
                        }

                        break;
                    }

                    // See 8.2.4.37 Before attribute value state
                    case AttributeState.BeforeValue:
                    {
                        c = SkipSpaces();

                        if (c == Symbols.DoubleQuote || c == Symbols.SingleQuote)
                        {
                            state = AttributeState.QuotedValue;
                            quote = c;
                        }
                        else if (c == Symbols.Ampersand)
                        {
                            state = AttributeState.UnquotedValue;
                        }
                        else if (c == Symbols.GreaterThan)
                        {
                            RaiseErrorOccurred(HtmlParseError.TagClosedWrong);
                            return EmitTag(tag);
                        }
                        else if (c == Symbols.LessThan || c == Symbols.Equality || c == Symbols.CurvedQuote)
                        {
                            RaiseErrorOccurred(HtmlParseError.AttributeValueInvalid);
                            StringBuffer.Append(c);
                            state = AttributeState.UnquotedValue;
                            c = GetNext();
                        }
                        else if (c == Symbols.Null)
                        {
                            AppendReplacement();
                            state = AttributeState.UnquotedValue;
                            c = GetNext();
                        }
                        else if (c != Symbols.EndOfFile)
                        {
                            StringBuffer.Append(c);
                            state = AttributeState.UnquotedValue;
                            c = GetNext();
                        }
                        else
                        {
                            return NewEof();
                        }

                        break;
                    }

                    // See 8.2.4.38 Attribute value (double-quoted) state
                    // and 8.2.4.39 Attribute value (single-quoted) state
                    case AttributeState.QuotedValue:
                    {
                        c = GetNext();

                        if (c == quote)
                        {
                            tag.SetAttributeValue(FlushBuffer());
                            state = AttributeState.AfterValue;
                        }
                        else if (c == Symbols.Ampersand)
                        {
                            AppendCharacterReference(GetNext(), quote);
                        }
                        else if (c == Symbols.Null)
                        {
                            AppendReplacement();
                        }
                        else if (c != Symbols.EndOfFile)
                        {
                            StringBuffer.Append(c);
                        }
                        else
                        {
                            return NewEof();
                        }

                        break;
                    }

                    // See 8.2.4.40 Attribute value (unquoted) state
                    case AttributeState.UnquotedValue:
                    {
                        if (c == Symbols.GreaterThan)
                        {
                            tag.SetAttributeValue(FlushBuffer());
                            return EmitTag(tag);
                        }
                        else if (c.IsSpaceCharacter())
                        {
                            tag.SetAttributeValue(FlushBuffer());
                            state = AttributeState.BeforeName;
                        }
                        else if (c == Symbols.Ampersand)
                        {
                            AppendCharacterReference(GetNext(), Symbols.GreaterThan);
                            c = GetNext();
                        }
                        else if (c == Symbols.Null)
                        {
                            AppendReplacement();
                            c = GetNext();
                        }
                        else if (c == Symbols.DoubleQuote || c == Symbols.SingleQuote || c == Symbols.LessThan || c == Symbols.Equality || c == Symbols.CurvedQuote)
                        {
                            RaiseErrorOccurred(HtmlParseError.AttributeValueInvalid);
                            StringBuffer.Append(c);
                            c = GetNext();
                        }
                        else if (c != Symbols.EndOfFile)
                        {
                            StringBuffer.Append(c);
                            c = GetNext();
                        }
                        else
                        {
                            return NewEof();
                        }

                        break;
                    }

                    // See 8.2.4.42 After attribute value (quoted) state
                    case AttributeState.AfterValue:
                    {
                        c = GetNext();

                        if (c == Symbols.GreaterThan)
                        {
                            return EmitTag(tag);
                        }
                        else if (c.IsSpaceCharacter())
                        {
                            state = AttributeState.BeforeName;
                        }
                        else if (c == Symbols.Solidus)
                        {
                            return TagSelfClosing(tag);
                        }
                        else if (c == Symbols.EndOfFile)
                        {
                            return NewEof();
                        }
                        else
                        {
                            RaiseErrorOccurred(HtmlParseError.AttributeNameExpected);
                            Back();
                            state = AttributeState.BeforeName;
                        }

                        break;
                    }
                }
            }
        }