Exemple #1
0
        public override bool Process(Token token)
        {
            // start tag, end tag, doctype, comment, character, eof
            switch (token.Type)
            {
            case TokenType.StartTag:
                Insert(token.AsStartTag());
                break;

            case TokenType.EndTag:
                PopStackToClose(token.AsEndTag());
                break;

            case TokenType.Comment:
                Insert(token.AsComment());
                break;

            case TokenType.Character:
                Insert(token.AsCharacter());
                break;

            case TokenType.Doctype:
                Insert(token.AsDoctype());
                break;

            case TokenType.EOF:     // could put some normalisation here if desired
                break;

            default:
                HtmlWarning.UnexpectedTokenType();
                break;
            }
            return(true);
        }
        private bool InSpecificScope(IReadOnlyCollection <string> targetNames, ICollection <string> baseTypes, ICollection <string> extraTypes)
        {
            IEnumerator <DomContainer> it = stack.GetDescendingEnumerator();

            while (it.MoveNext())
            {
                var    el     = it.Current;
                string elName = el.NodeName;
                if (targetNames.Contains(elName))
                {
                    return(true);
                }

                if (baseTypes.Contains(elName))
                {
                    return(false);
                }

                if (extraTypes != null && extraTypes.Contains(elName))
                {
                    return(false);
                }
            }

            HtmlWarning.ShouldNotBeReachable();
            return(false);
        }
Exemple #3
0
        public void Emit(Token token)
        {
            if (isEmitPending)
            {
                HtmlWarning.UnreadTokenPending();
            }

            emitPending   = token;
            isEmitPending = true;
            if (token.Type == TokenType.StartTag)
            {
                Token.StartTag startTag = (Token.StartTag)token;
                lastStartTag = startTag;

                if (startTag.selfClosing)
                {
                    selfClosingFlagAcknowledged = false;
                }
            }
            else if (token.Type == TokenType.EndTag)
            {
                Token.EndTag endTag = (Token.EndTag)token;

                if (endTag.Attributes.Any())
                {
                    ParseError.AttributesPresentOnEndTagError(this);
                }
            }
        }
        public DomContainer Pop()
        {
            // TODO - dev, remove validation check
            if (stack.Last.Value.NodeName.Equals("td") && !_state.Name.Equals("InCellState"))
            {
                HtmlWarning.PoppingTDNotInCell();
            }

            if (stack.Last.Value.NodeName.Equals("html"))
            {
                HtmlWarning.PoppingHtml();
            }

            var last = stack.Last.Value;

            stack.RemoveLast();
            return(last);
        }
        public DomContainer AboveOnStack(DomContainer el)
        {
            if (!OnStack(el))
            {
                HtmlWarning.ElementShouldBeOnStack();
            }
            var it = stack.GetDescendingEnumerator();

            while (it.MoveNext())
            {
                var next = it.Current;

                if (next == el)
                {
                    it.MoveNext();
                    return(it.Current);
                }
            }
            return(null);
        }
        public bool InSelectScope(string targetName)
        {
            IEnumerator <DomContainer> it = stack.GetDescendingEnumerator();

            while (it.MoveNext())
            {
                var    el     = it.Current;
                string elName = el.NodeName;
                if (elName.Equals(targetName))
                {
                    return(true);
                }

                if (!StringUtil.In(elName, "optgroup", "option")) // all elements except
                {
                    return(false);
                }
            }

            HtmlWarning.ShouldNotBeReachable();
            return(false);
        }
        public void InsertInFosterParent(DomNode input)
        {
            DomContainer fosterParent      = null;
            var          lastTable         = GetFromStack("table");
            bool         isLastTableParent = false;

            if (lastTable != null)
            {
                if (lastTable.Parent != null)
                {
                    fosterParent      = lastTable.Parent;
                    isLastTableParent = true;
                }
                else
                {
                    fosterParent = AboveOnStack(lastTable);
                }
            }
            else     // no table == frag
            {
                fosterParent = stack.ElementAt(0);
            }

            if (isLastTableParent)
            {
                // last table cannot be null by this point.
                if (lastTable == null)
                {
                    HtmlWarning.FosterParentTableUnexpectedlyNull();
                }

                lastTable.Before(input);
            }
            else
            {
                fosterParent.Append(input);
            }
        }
        public void ReconstructFormattingElements()
        {
            int size = formattingElements.Count;

            if (size == 0 || formattingElements.Last.Value == null || OnStack(formattingElements.Last.Value))
            {
                return;
            }

            var  entry = formattingElements.Last.Value;
            int  pos   = size - 1;
            bool skip  = false;

            while (true)
            {
                if (pos == 0) // step 4. if none before, skip to 8
                {
                    skip = true;
                    break;
                }
                entry = formattingElements.ElementAt(--pos); // step 5. one earlier than entry
                if (entry == null || OnStack(entry))         // step 6 - neither marker nor on stack
                {
                    break;                                   // jump to 8, else continue back to 4
                }
            }

            while (true)
            {
                if (!skip) // step 7: on later than entry
                {
                    entry = formattingElements.ElementAt(++pos);
                }

                if (entry == null)
                {
                    HtmlWarning.ReconstructUnexpectedlyEmpty();
                    // should not occur, as we break at last element
                }

                // 8. create new element from element, 9 insert into current node, onto stack
                skip = false;                               // can only skip increment from 4.
                HtmlElement newEl = Insert(entry.NodeName); // todo: avoid fostering here?
                // newEl.namespace(entry.namespace()); // todo: namespaces

                foreach (var attr in entry.Attributes)
                {
                    newEl.Attributes.Add(attr.Clone());
                }

                // 10. replace entry with new entry
                formattingElements.AddBefore(formattingElements.Find(entry), newEl);
                formattingElements.Remove(entry);

                // 11
                if (pos == size - 1) // if not last entry in list, jump to 7
                {
                    break;
                }
            }
        }