Beispiel #1
0
        /// <summary>
        /// Setups a new SVG element with the attributes from the token.
        /// </summary>
        /// <param name="element">The element to setup.</param>
        /// <param name="tag">The tag token to use.</param>
        /// <returns>The finished element.</returns>
        public static SvgElement Setup(this SvgElement element, HtmlTagToken tag)
        {
            var count = tag.Attributes.Count;

            for (var i = 0; i < count; i++)
            {
                var name  = tag.Attributes[i].Key;
                var value = tag.Attributes[i].Value;
                element.AdjustAttribute(name.AdjustToSvgAttribute(), value);
            }

            return(element);
        }
        /// <summary>
        /// See 8.2.4.40 Attribute value (unquoted) state
        /// </summary>
        /// <param name="c">The next input character.</param>
        /// <param name="tag">The current tag token.</param>
        /// <returns>The emitted token.</returns>
        HtmlToken AttributeUnquotedValue(Char c, HtmlTagToken tag)
        {
            while (true)
            {
                if (c.IsSpaceCharacter())
                {
                    tag.SetAttributeValue(_stringBuffer.ToString());
                    return AttributeBeforeName(Next, tag);
                }
                else if (c == Specification.Ampersand)
                {
                    var value = CharacterReference(Next, Specification.GreaterThan);

                    if (value == null)
                        _stringBuffer.Append(Specification.Ampersand);
                    else
                        _stringBuffer.Append(value);
                }
                else if (c == Specification.GreaterThan)
                {
                    tag.SetAttributeValue(_stringBuffer.ToString());
                    return EmitTag(tag);
                }
                else if (c == Specification.Null)
                {
                    RaiseErrorOccurred(ErrorCode.Null);
                    _stringBuffer.Append(Specification.Replacement);
                }
                else if (c == Specification.DoubleQuote || c == Specification.SingleQuote || c == Specification.LessThan || c == Specification.Equality || c == Specification.CurvedQuote)
                {
                    RaiseErrorOccurred(ErrorCode.AttributeValueInvalid);
                    _stringBuffer.Append(c);
                }
                else if (c == Specification.EndOfFile)
                    return HtmlToken.EOF;
                else
                    _stringBuffer.Append(c);

                c = Next;
            }
        }
        /// <summary>
        /// See 8.2.4.35 Attribute name state
        /// </summary>
        /// <param name="c">The next input character.</param>
        /// <param name="tag">The current tag token.</param>
        /// <returns>The emitted token.</returns>
        HtmlToken AttributeName(Char c, HtmlTagToken tag)
        {
            while (true)
            {
                if (c.IsSpaceCharacter())
                {
                    tag.AddAttribute(_stringBuffer.ToString());
                    return AttributeAfterName(Next, tag);
                }
                else if (c == Specification.Solidus)
                {
                    tag.AddAttribute(_stringBuffer.ToString());
                    return TagSelfClosing(Next, tag);
                }
                else if (c == Specification.Equality)
                {
                    tag.AddAttribute(_stringBuffer.ToString());
                    return AttributeBeforeValue(Next, tag);
                }
                else if (c == Specification.GreaterThan)
                {
                    tag.AddAttribute(_stringBuffer.ToString());
                    return EmitTag(tag);
                }
                else if (c == Specification.EndOfFile)
                    return HtmlToken.EOF;
                else if (c == Specification.Null)
                {
                    RaiseErrorOccurred(ErrorCode.Null);
                    _stringBuffer.Append(Specification.Replacement);
                }
                else if (c.IsUppercaseAscii())
                    _stringBuffer.Append(Char.ToLower(c));
                else if (c == Specification.DoubleQuote || c == Specification.SingleQuote || c == Specification.LessThan)
                {
                    RaiseErrorOccurred(ErrorCode.AttributeNameInvalid);
                    _stringBuffer.Append(c);
                }
                else
                    _stringBuffer.Append(c);

                c = Next;
            }
        }
        /// <summary>
        /// See 8.2.4.39 Attribute value (single-quoted) state
        /// </summary>
        /// <param name="c">The next input character.</param>
        /// <param name="tag">The current tag token.</param>
        /// <returns>The emitted token.</returns>
        HtmlToken AttributeSingleQuotedValue(Char c, HtmlTagToken tag)
        {
            while (true)
            {
                if (c == Specification.SingleQuote)
                {
                    tag.SetAttributeValue(_stringBuffer.ToString());
                    return AttributeAfterValue(Next, tag);
                }
                else if (c == Specification.Ampersand)
                {
                    var value = CharacterReference(Next, Specification.SingleQuote);

                    if (value == null)
                        _stringBuffer.Append(Specification.Ampersand);
                    else
                        _stringBuffer.Append(value);
                }
                else if (c == Specification.Null)
                {
                    RaiseErrorOccurred(ErrorCode.Null);
                    _stringBuffer.Append(Specification.Replacement);
                }
                else if (c == Specification.EndOfFile)
                    return HtmlToken.EOF;
                else
                    _stringBuffer.Append(c);

                c = Next;
            }
        }
 /// <summary>
 /// See 8.2.4.43 Self-closing start tag state
 /// </summary>
 /// <param name="c">The next input character.</param>
 /// <param name="tag">The current tag token.</param>
 /// <returns>The emitted token.</returns>
 HtmlToken TagSelfClosing(Char c, HtmlTagToken tag)
 {
     if (c == Specification.GreaterThan)
     {
         tag.IsSelfClosing = true;
         return EmitTag(tag);
     }
     else if (c == Specification.EndOfFile)
     {
         RaiseErrorOccurred(ErrorCode.EOF);
         return HtmlToken.EOF;
     }
     else
     {
         RaiseErrorOccurred(ErrorCode.ClosingSlashMisplaced);
         return AttributeBeforeName(c, tag);
     }
 }
        /// <summary>
        /// See 8.2.4.37 Before attribute value state
        /// </summary>
        /// <param name="c">The next input character.</param>
        /// <param name="tag">The current tag token.</param>
        /// <returns>The emitted token.</returns>
        HtmlToken AttributeBeforeValue(Char c, HtmlTagToken tag)
        {
            while (c.IsSpaceCharacter())
                c = Next;

            if (c == Specification.DoubleQuote)
            {
                _stringBuffer.Clear();
                return AttributeDoubleQuotedValue(Next, tag);
            }
            else if (c == Specification.Ampersand)
            {
                _stringBuffer.Clear();
                return AttributeUnquotedValue(c, tag);
            }
            else if (c == Specification.SingleQuote)
            {
                _stringBuffer.Clear();
                return AttributeSingleQuotedValue(Next, tag);
            }
            else if (c == Specification.Null)
            {
                RaiseErrorOccurred(ErrorCode.Null);
                _stringBuffer.Append(Specification.Replacement);
                return AttributeUnquotedValue(Next, tag);
            }
            else if (c == Specification.GreaterThan)
            {
                RaiseErrorOccurred(ErrorCode.TagClosedWrong);
                return EmitTag(tag);
            }
            else if (c == Specification.LessThan || c == Specification.Equality || c == Specification.CurvedQuote)
            {
                RaiseErrorOccurred(ErrorCode.AttributeValueInvalid);
                _stringBuffer.Clear().Append(c);
                return AttributeUnquotedValue(Next, tag);
            }
            else if (c == Specification.EndOfFile)
            {
                return HtmlToken.EOF;
            }
            else
            {
                _stringBuffer.Clear().Append(c);
                return AttributeUnquotedValue(Next, tag);
            }
        }
        /// <summary>
        /// See 8.2.4.10 Tag name state
        /// </summary>
        /// <param name="c">The next input character.</param>
        /// <param name="tag">The current tag token.</param>
        /// <returns>The emitted token.</returns>
        HtmlToken TagName(Char c, HtmlTagToken tag)
        {
            while (true)
            {
                if (c.IsSpaceCharacter())
                {
                    tag.Name = _stringBuffer.ToString();
                    return AttributeBeforeName(Next, tag);
                }
                else if (c == Specification.Solidus)
                {
                    tag.Name = _stringBuffer.ToString();
                    return TagSelfClosing(Next, tag);
                }
                else if (c == Specification.GreaterThan)
                {
                    tag.Name = _stringBuffer.ToString();
                    return EmitTag(tag);
                }
                else if (c == Specification.Null)
                {
                    RaiseErrorOccurred(ErrorCode.Null);
                    _stringBuffer.Append(Specification.Replacement);
                }
                else if (c == Specification.EndOfFile)
                {
                    RaiseErrorOccurred(ErrorCode.EOF);
                    return HtmlToken.EOF;
                }
                else if (c.IsUppercaseAscii())
                    _stringBuffer.Append(Char.ToLower(c));
                else
                    _stringBuffer.Append(c);

                c = Next;
            }
        }
        /// <summary>
        /// See 8.2.4.19 Script data end tag name state
        /// </summary>
        /// <param name="c">The next input character.</param>
        /// <param name="tag">The current tag token.</param>
        /// <returns>The emitted token.</returns>
        HtmlToken ScriptDataNameEndTag(Char c, HtmlTagToken tag)
        {
            var name = _stringBuffer.ToString().ToLower();
            var appropriateEndTag = name == _lastStartTag;

            if (appropriateEndTag && c.IsSpaceCharacter())
            {
                tag.Name = name;
                return AttributeBeforeName(Next, tag);
            }
            else if (appropriateEndTag && c == Specification.Solidus)
            {
                tag.Name = name;
                return TagSelfClosing(Next, tag);
            }
            else if (appropriateEndTag && c == Specification.GreaterThan)
            {
                tag.Name = name;
                return EmitTag(tag);
            }
            else if (c.IsLetter())
            {
                _stringBuffer.Append(c);
                return ScriptDataNameEndTag(Next, tag);
            }

            _buffer.Append(Specification.LessThan).Append(Specification.Solidus);
            _buffer.Append(_stringBuffer.ToString());
            return ScriptData(c);
        }
        /// <summary>
        /// See 8.2.4.26 Script data escaped end tag open state
        /// </summary>
        /// <param name="c">The next input character.</param>
        /// <param name="tag">The current tag token.</param>
        /// <returns>The emitted token.</returns>
        HtmlToken ScriptDataEscapedEndTag(Char c, HtmlTagToken tag)
        {
            if (c.IsLetter())
            {
                _stringBuffer.Clear();
                _stringBuffer.Append(c);
                return ScriptDataEscapedEndTag(Next, tag);
            }

            _buffer.Append(Specification.LessThan).Append(Specification.Solidus);
            return ScriptDataEscaped(c);
        }
        /// <summary>
        /// See 8.2.4.42 After attribute value (quoted) state
        /// </summary>
        /// <param name="c">The next input character.</param>
        /// <param name="tag">The current tag token.</param>
        /// <returns>The emitted token.</returns>
        HtmlToken AttributeAfterValue(Char c, HtmlTagToken tag)
        {
            if (c.IsSpaceCharacter())
                return AttributeBeforeName(Next, tag);
            else if (c == Specification.Solidus)
                return TagSelfClosing(Next, tag);
            else if (c == Specification.GreaterThan)
                return EmitTag(tag);
            else if (c == Specification.EndOfFile)
                return HtmlTagToken.EOF;

            RaiseErrorOccurred(ErrorCode.AttributeNameExpected);
            return AttributeBeforeName(c, tag);
        }
        /// <summary>
        /// Emits the current token as a tag token.
        /// </summary>
        HtmlTagToken EmitTag(HtmlTagToken tag)
        {
            _state = HtmlParseMode.PCData;

            if (tag.Type == HtmlTokenType.StartTag)
            {
                for (var i = tag.Attributes.Count - 1; i > 0; i--)
                {
                    for (var j = i - 1; j >= 0; j--)
                    {
                        if (tag.Attributes[j].Key == tag.Attributes[i].Key)
                        {
                            tag.Attributes.RemoveAt(i);
                            RaiseErrorOccurred(ErrorCode.AttributeDuplicateOmitted);
                            break;
                        }
                    }
                }

                _lastStartTag = tag.Name;
            }
            else
            {
                if (tag.IsSelfClosing)
                    RaiseErrorOccurred(ErrorCode.EndTagCannotBeSelfClosed);

                if (tag.Attributes.Count != 0)
                    RaiseErrorOccurred(ErrorCode.EndTagCannotHaveAttributes);
            }

            return tag;
        }