コード例 #1
0
        /// <summary>
        /// Gets a HTML attribute type
        /// </summary>
        /// <param name="tagNameInLowercase">Tag name in lowercase</param>
        /// <param name="tagFlags">Tag flags</param>
        /// <param name="attributeNameInLowercase">Attribute name in lowercase</param>
        /// <param name="attributes">List of attributes</param>
        /// <returns>Attribute type</returns>
        public HtmlAttributeType GetAttributeType(string tagNameInLowercase, HtmlTagFlags tagFlags,
                                                  string attributeNameInLowercase, List <HtmlAttribute> attributes)
        {
            HtmlAttributeType attributeType = HtmlAttributeType.Unknown;

            if (attributeNameInLowercase == "class")
            {
                attributeType = HtmlAttributeType.ClassName;
            }
            else if (attributeNameInLowercase == "style")
            {
                attributeType = HtmlAttributeType.Style;
            }
            else if (IsEventAttribute(attributeNameInLowercase))
            {
                attributeType = HtmlAttributeType.Event;
            }

            if (attributeType == HtmlAttributeType.Unknown && !tagFlags.IsSet(HtmlTagFlags.Xml))
            {
                if (IsBooleanAttribute(attributeNameInLowercase))
                {
                    attributeType = HtmlAttributeType.Boolean;
                }
                else if (IsNumericAttribute(tagNameInLowercase, attributeNameInLowercase))
                {
                    attributeType = HtmlAttributeType.Numeric;
                }
                else if (IsUriBasedAttribute(tagNameInLowercase, attributeNameInLowercase,
                                             attributes))
                {
                    attributeType = HtmlAttributeType.Uri;
                }
            }

            if (attributeType == HtmlAttributeType.Unknown)
            {
                attributeType = IsXmlBasedAttribute(attributeNameInLowercase) ?
                                HtmlAttributeType.Xml : HtmlAttributeType.Text;
            }

            return(attributeType);
        }
コード例 #2
0
ファイル: HtmlParser.cs プロジェクト: timheuer/WebMarkupMin
        /// <summary>
        /// Parses a end tag
        /// </summary>
        /// <param name="tagName">Tag name</param>
        /// <param name="tagNameInLowercase">Tag name in lowercase</param>
        private void ParseEndTag(string tagName, string tagNameInLowercase)
        {
            int  endTagIndex     = 0;
            int  lastTagIndex    = _tagStack.Count - 1;
            bool tagNameNotEmpty = !string.IsNullOrEmpty(tagName);

            HtmlParsingHandlers.EndTagDelegate endTagHandler = _handlers.EndTag;

            if (tagNameNotEmpty)
            {
                for (endTagIndex = lastTagIndex; endTagIndex >= 0; endTagIndex--)
                {
                    if (_tagStack[endTagIndex].NameInLowercase == tagNameInLowercase)
                    {
                        break;
                    }
                }
            }

            if (endTagIndex >= 0)
            {
                // Close all the open elements, up the stack
                if (endTagHandler != null)
                {
                    for (int tagIndex = lastTagIndex; tagIndex >= endTagIndex; tagIndex--)
                    {
                        HtmlTag      startTag = _tagStack[tagIndex];
                        string       startTagNameInLowercase = startTag.NameInLowercase;
                        HtmlTagFlags startTagFlags           = startTag.Flags;

                        string endTagName;
                        if (tagNameNotEmpty && tagNameInLowercase == startTagNameInLowercase)
                        {
                            endTagName = tagName;
                        }
                        else
                        {
                            endTagName = startTag.Name;
                        }

                        if (_xmlTagStack.Count > 0 && !startTagFlags.IsSet(HtmlTagFlags.NonIndependent))
                        {
                            _xmlTagStack.Pop();
                        }

                        var endTag = new HtmlTag(endTagName, startTagNameInLowercase, startTagFlags);
                        endTagHandler(_context, endTag);
                    }
                }

                // Remove the open elements from the stack
                if (endTagIndex <= lastTagIndex)
                {
                    int tagToRemoveStartIndex = endTagIndex;
                    int tagsToRemoveCount     = lastTagIndex - endTagIndex + 1;

                    _tagStack.RemoveRange(tagToRemoveStartIndex, tagsToRemoveCount);
                }
            }
            else if (tagNameNotEmpty && _conditionalCommentOpened)
            {
                if (_xmlTagStack.Count > 0 && _tagTypeDeterminer.IsXmlBasedTag(tagNameInLowercase))
                {
                    _xmlTagStack.Pop();
                }

                var endTag = new HtmlTag(tagName, tagNameInLowercase, GetTagFlagsByName(tagNameInLowercase));
                endTagHandler?.Invoke(_context, endTag);
            }
        }
コード例 #3
0
ファイル: HtmlParser.cs プロジェクト: timheuer/WebMarkupMin
        /// <summary>
        /// Parses a start tag
        /// </summary>
        /// <param name="tagName">Tag name</param>
        /// <param name="tagNameInLowercase">Tag name in lowercase</param>
        /// <param name="attributes">List of attributes</param>
        /// <param name="isEmptyTag">Flag that tag is empty</param>
        private void ParseStartTag(string tagName, string tagNameInLowercase, List <HtmlAttribute> attributes,
                                   bool isEmptyTag)
        {
            HtmlTagFlags tagFlags = GetTagFlagsByName(tagNameInLowercase);

            if (tagFlags.IsSet(HtmlTagFlags.Optional))
            {
                HtmlTag lastStackedTag = _tagStack.LastOrDefault();
                if (lastStackedTag != null && lastStackedTag.NameInLowercase == tagNameInLowercase)
                {
                    ParseEndTag(lastStackedTag.Name, lastStackedTag.NameInLowercase);
                }
                else
                {
                    if (tagNameInLowercase == "body" && _tagStack.Any(t => t.NameInLowercase == "head"))
                    {
                        HtmlTag headTag = _tagStack.First(t => t.NameInLowercase == "head");
                        ParseEndTag(headTag.Name, headTag.NameInLowercase);
                    }
                }
            }

            if (tagFlags.IsSet(HtmlTagFlags.Empty))
            {
                isEmptyTag = true;
            }
            else if (isEmptyTag)
            {
                tagFlags |= HtmlTagFlags.Empty;
            }

            int attributeCount = attributes.Count;

            for (int attributeIndex = 0; attributeIndex < attributeCount; attributeIndex++)
            {
                HtmlAttribute attribute = attributes[attributeIndex];
                attribute.Type = _attributeTypeDeterminer.GetAttributeType(tagNameInLowercase, tagFlags,
                                                                           attribute.NameInLowercase, attributes);
            }

            var tag = new HtmlTag(tagName, tagNameInLowercase, attributes, tagFlags);

            if (!isEmptyTag)
            {
                if (_conditionalCommentOpened)
                {
                    HtmlConditionalComment     lastConditionalComment     = _conditionalCommentStack.Peek();
                    HtmlConditionalCommentType lastConditionalCommentType = lastConditionalComment.Type;

                    if (tagFlags.IsSet(HtmlTagFlags.EmbeddedCode) ||
                        lastConditionalCommentType == HtmlConditionalCommentType.RevealedValidating ||
                        lastConditionalCommentType == HtmlConditionalCommentType.RevealedValidatingSimplified)
                    {
                        _tagStack.Add(tag);
                    }
                }
                else
                {
                    _tagStack.Add(tag);
                }
            }

            _handlers.StartTag?.Invoke(_context, tag);

            if (tagFlags.IsSet(HtmlTagFlags.Xml) && !tagFlags.IsSet(HtmlTagFlags.NonIndependent))
            {
                _xmlTagStack.Push(tagNameInLowercase);
            }
        }